From 470dbe209ebe31b3a19a5666ec16d5601955ee63 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 8 Jul 2024 14:44:54 +0200 Subject: [PATCH 01/47] Extract IDs for realtime tests --- .../siri/SiriTimetableSnapshotSourceTest.java | 56 ++++++------- .../updater/trip/RealtimeTestEnvironment.java | 80 ++++++++++++++----- .../CancellationDeletionTest.java | 31 +++---- .../trip/moduletests/delay/DelayedTest.java | 18 ++--- .../trip/moduletests/delay/SkippedTest.java | 18 ++--- .../rejection/InvalidInputTest.java | 5 +- 6 files changed, 118 insertions(+), 90 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java index 45e7979b353..ea94d4b9505 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java @@ -2,6 +2,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertFailure; +import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.OPERATOR_1_ID; +import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.ROUTE_1_ID; import java.util.Set; import org.junit.jupiter.api.Disabled; @@ -16,17 +18,17 @@ class SiriTimetableSnapshotSourceTest { void testCancelTrip() { var env = RealtimeTestEnvironment.siri(); - assertEquals(RealTimeState.SCHEDULED, env.getTripTimesForTrip(env.trip1).getRealTimeState()); + assertEquals(RealTimeState.SCHEDULED, env.getTripTimesForTrip(env.trip1()).getRealTimeState()); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(env.trip1.getId().getId()) + .withDatedVehicleJourneyRef(RealtimeTestEnvironment.TRIP_1_ID) .withCancellation(true) .buildEstimatedTimetableDeliveries(); var result = env.applyEstimatedTimetable(updates); assertEquals(1, result.successful()); - assertEquals(RealTimeState.CANCELED, env.getTripTimesForTrip(env.trip1).getRealTimeState()); + assertEquals(RealTimeState.CANCELED, env.getTripTimesForTrip(env.trip1()).getRealTimeState()); } @Test @@ -36,8 +38,8 @@ void testAddJourney() { var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withEstimatedVehicleJourneyCode("newJourney") .withIsExtraJourney(true) - .withOperatorRef(env.operator1Id.getId()) - .withLineRef(env.route1Id.getId()) + .withOperatorRef(OPERATOR_1_ID) + .withLineRef(ROUTE_1_ID) .withRecordedCalls(builder -> builder.call(env.stopC1).departAimedActual("00:01", "00:02")) .withEstimatedCalls(builder -> builder.call(env.stopD1).arriveAimedExpected("00:03", "00:04")) .buildEstimatedTimetableDeliveries(); @@ -61,8 +63,8 @@ void testAddedJourneyWithInvalidScheduledData() { var createExtraJourney = new SiriEtBuilder(env.getDateTimeHelper()) .withEstimatedVehicleJourneyCode("newJourney") .withIsExtraJourney(true) - .withOperatorRef(env.operator1Id.getId()) - .withLineRef(env.route1Id.getId()) + .withOperatorRef(OPERATOR_1_ID) + .withLineRef(ROUTE_1_ID) .withEstimatedCalls(builder -> builder .call(env.stopA1) @@ -109,9 +111,9 @@ void testReplaceJourney() { .withEstimatedVehicleJourneyCode("newJourney") .withIsExtraJourney(true) // replace trip1 - .withVehicleJourneyRef(env.trip1.getId().getId()) - .withOperatorRef(env.operator1Id.getId()) - .withLineRef(env.route1Id.getId()) + .withVehicleJourneyRef(RealtimeTestEnvironment.TRIP_1_ID) + .withOperatorRef(OPERATOR_1_ID) + .withLineRef(ROUTE_1_ID) .withRecordedCalls(builder -> builder.call(env.stopA1).departAimedActual("00:01", "00:02")) .withEstimatedCalls(builder -> builder.call(env.stopC1).arriveAimedExpected("00:03", "00:04")) .buildEstimatedTimetableDeliveries(); @@ -127,7 +129,7 @@ void testReplaceJourney() { ); // Original trip should not get canceled - var originalTripTimes = env.getTripTimesForTrip(env.trip1); + var originalTripTimes = env.getTripTimesForTrip(env.trip1()); assertEquals(RealTimeState.SCHEDULED, originalTripTimes.getRealTimeState()); } @@ -139,14 +141,14 @@ void testUpdateJourneyWithDatedVehicleJourneyRef() { var env = RealtimeTestEnvironment.siri(); var updates = updatedJourneyBuilder(env) - .withDatedVehicleJourneyRef(env.trip1.getId().getId()) + .withDatedVehicleJourneyRef(RealtimeTestEnvironment.TRIP_1_ID) .buildEstimatedTimetableDeliveries(); var result = env.applyEstimatedTimetable(updates); assertEquals(1, result.successful()); assertTripUpdated(env); assertEquals( "UPDATED | A1 0:00:15 0:00:15 | B1 0:00:25 0:00:25", - env.getRealtimeTimetable(env.trip1) + env.getRealtimeTimetable(env.trip1()) ); } @@ -161,7 +163,7 @@ void testUpdateJourneyWithFramedVehicleJourneyRef() { .withFramedVehicleJourneyRef(builder -> builder .withServiceDate(RealtimeTestEnvironment.SERVICE_DATE) - .withVehicleJourneyRef(env.trip1.getId().getId()) + .withVehicleJourneyRef(RealtimeTestEnvironment.TRIP_1_ID) ) .buildEstimatedTimetableDeliveries(); var result = env.applyEstimatedTimetable(updates); @@ -229,7 +231,7 @@ void testChangeQuay() { var env = RealtimeTestEnvironment.siri(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(env.trip1.getId().getId()) + .withDatedVehicleJourneyRef(RealtimeTestEnvironment.TRIP_1_ID) .withRecordedCalls(builder -> builder.call(env.stopA1).departAimedActual("00:00:11", "00:00:15") ) @@ -243,7 +245,7 @@ void testChangeQuay() { assertEquals(1, result.successful()); assertEquals( "MODIFIED | A1 [R] 0:00:15 0:00:15 | B2 0:00:33 0:00:33", - env.getRealtimeTimetable(env.trip1) + env.getRealtimeTimetable(env.trip1()) ); } @@ -252,7 +254,7 @@ void testCancelStop() { var env = RealtimeTestEnvironment.siri(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(env.trip2.getId().getId()) + .withDatedVehicleJourneyRef(env.trip2().getId().getId()) .withEstimatedCalls(builder -> builder .call(env.stopA1) @@ -269,7 +271,7 @@ void testCancelStop() { assertEquals(1, result.successful()); assertEquals( "MODIFIED | A1 0:01:01 0:01:01 | B1 [C] 0:01:10 0:01:11 | C1 0:01:30 0:01:30", - env.getRealtimeTimetable(env.trip2) + env.getRealtimeTimetable(env.trip2()) ); } @@ -280,7 +282,7 @@ void testAddStop() { var env = RealtimeTestEnvironment.siri(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(env.trip1.getId().getId()) + .withDatedVehicleJourneyRef(RealtimeTestEnvironment.TRIP_1_ID) .withRecordedCalls(builder -> builder.call(env.stopA1).departAimedActual("00:00:11", "00:00:15") ) @@ -300,7 +302,7 @@ void testAddStop() { assertEquals(1, result.successful()); assertEquals( "MODIFIED | A1 0:00:15 0:00:15 | D1 [C] 0:00:20 0:00:25 | B1 0:00:33 0:00:33", - env.getRealtimeTimetable(env.trip1) + env.getRealtimeTimetable(env.trip1()) ); } @@ -328,9 +330,9 @@ void testReplaceJourneyWithoutEstimatedVehicleJourneyCode() { var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withDatedVehicleJourneyRef("newJourney") .withIsExtraJourney(true) - .withVehicleJourneyRef(env.trip1.getId().getId()) - .withOperatorRef(env.operator1Id.getId()) - .withLineRef(env.route1Id.getId()) + .withVehicleJourneyRef(RealtimeTestEnvironment.TRIP_1_ID) + .withOperatorRef(OPERATOR_1_ID) + .withLineRef(ROUTE_1_ID) .withEstimatedCalls(builder -> builder .call(env.stopA1) @@ -351,7 +353,7 @@ void testNegativeHopTime() { var env = RealtimeTestEnvironment.siri(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(env.trip1.getId().getId()) + .withDatedVehicleJourneyRef(RealtimeTestEnvironment.TRIP_1_ID) .withRecordedCalls(builder -> builder .call(env.stopA1) @@ -371,7 +373,7 @@ void testNegativeDwellTime() { var env = RealtimeTestEnvironment.siri(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(env.trip2.getId().getId()) + .withDatedVehicleJourneyRef(env.trip2().getId().getId()) .withRecordedCalls(builder -> builder .call(env.stopA1) @@ -396,7 +398,7 @@ void testExtraUnknownStop() { var env = RealtimeTestEnvironment.siri(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(env.trip1.getId().getId()) + .withDatedVehicleJourneyRef(RealtimeTestEnvironment.TRIP_1_ID) .withEstimatedCalls(builder -> builder .call(env.stopA1) @@ -429,7 +431,7 @@ private static SiriEtBuilder updatedJourneyBuilder(RealtimeTestEnvironment env) private static void assertTripUpdated(RealtimeTestEnvironment env) { assertEquals( "UPDATED | A1 0:00:15 0:00:15 | B1 0:00:25 0:00:25", - env.getRealtimeTimetable(env.trip1) + env.getRealtimeTimetable(env.trip1()) ); } } diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java index bf6f743eac7..ba26ed97f79 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java @@ -50,6 +50,7 @@ */ public final class RealtimeTestEnvironment { + // static constants private static final TimetableSnapshotSourceParameters PARAMETERS = new TimetableSnapshotSourceParameters( Duration.ZERO, false @@ -59,6 +60,12 @@ public final class RealtimeTestEnvironment { public static final String STOP_A1_ID = "A1"; public static final String STOP_B1_ID = "B1"; public static final String STOP_C1_ID = "C1"; + public static final String TRIP_1_ID = "TestTrip1"; + public static final String TRIP_2_ID = "TestTrip2"; + public static final String OPERATOR_1_ID = "TestOperator1"; + public static final String ROUTE_1_ID = "TestRoute1"; + + // instance variables private final TransitModelForTest testModel = TransitModelForTest.of(); public final ZoneId timeZone = ZoneId.of(TransitModelForTest.TIME_ZONE_ID); public final Station stationA = testModel.station("A").build(); @@ -78,15 +85,17 @@ public final class RealtimeTestEnvironment { .withRegularStop(stopC1) .withRegularStop(stopD1) .build(); - public final FeedScopedId operator1Id = TransitModelForTest.id("TestOperator1"); - public final FeedScopedId route1Id = TransitModelForTest.id("TestRoute1"); - public final Trip trip1; - public final Trip trip2; + + public final Route route1 = TransitModelForTest.route(ROUTE_1_ID).build(); + public final TransitModel transitModel; private final SiriTimetableSnapshotSource siriSource; private final TimetableSnapshotSource gtfsSource; private final DateTimeHelper dateTimeHelper; + private Trip trip1; + private Trip trip2; + private enum SourceType { GTFS_RT, SIRI, @@ -111,24 +120,8 @@ private RealtimeTestEnvironment(SourceType sourceType) { transitModel.initTimeZone(timeZone); transitModel.addAgency(TransitModelForTest.AGENCY); - Route route1 = TransitModelForTest.route(route1Id).build(); - - trip1 = - createTrip( - "TestTrip1", - route1, - List.of(new StopCall(stopA1, 10, 11), new StopCall(stopB1, 20, 21)) - ); - trip2 = - createTrip( - "TestTrip2", - route1, - List.of( - new StopCall(stopA1, 60, 61), - new StopCall(stopB1, 70, 71), - new StopCall(stopC1, 80, 81) - ) - ); + withTrip1(); + withTrip2(); CalendarServiceData calendarServiceData = new CalendarServiceData(); calendarServiceData.putServiceDatesForServiceId( @@ -153,6 +146,49 @@ private RealtimeTestEnvironment(SourceType sourceType) { dateTimeHelper = new DateTimeHelper(timeZone, RealtimeTestEnvironment.SERVICE_DATE); } + public RealtimeTestEnvironment withTrip1() { + trip1 = + createTrip( + TRIP_1_ID, + route1, + List.of(new StopCall(stopA1, 10, 11), new StopCall(stopB1, 20, 21)) + ); + transitModel.index(); + return this; + } + + public RealtimeTestEnvironment withTrip2() { + trip2 = + createTrip( + TRIP_2_ID, + route1, + List.of( + new StopCall(stopA1, 60, 61), + new StopCall(stopB1, 70, 71), + new StopCall(stopC1, 80, 81) + ) + ); + + transitModel.index(); + return this; + } + + public Trip trip1() { + Objects.requireNonNull( + trip1, + "trip1 was not added to the test environment. Call withTrip1() to add it." + ); + return trip1; + } + + public Trip trip2() { + Objects.requireNonNull( + trip2, + "trip2 was not added to the test environment. Call withTrip2() to add it." + ); + return trip2; + } + public static FeedScopedId id(String id) { return TransitModelForTest.id(id); } diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java index c85225b7828..57d48fa9db3 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java @@ -5,6 +5,8 @@ import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertSuccess; +import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.SERVICE_DATE; +import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.TRIP_1_ID; import static org.opentripplanner.updater.trip.UpdateIncrementality.DIFFERENTIAL; import com.google.transit.realtime.GtfsRealtime.TripDescriptor.ScheduleRelationship; @@ -32,22 +34,16 @@ static List cases() { @ParameterizedTest @MethodSource("cases") void cancelledTrip(ScheduleRelationship relationship, RealTimeState state) { - var env = RealtimeTestEnvironment.gtfs(); - var pattern1 = env.getPatternForTrip(env.trip1); + var env = RealtimeTestEnvironment.gtfs().withTrip1(); + var pattern1 = env.getPatternForTrip(env.trip1()); - final int tripIndex1 = pattern1.getScheduledTimetable().getTripIndex(env.trip1.getId()); + final int tripIndex1 = pattern1.getScheduledTimetable().getTripIndex(env.trip1().getId()); - var update = new TripUpdateBuilder( - env.trip1.getId().getId(), - RealtimeTestEnvironment.SERVICE_DATE, - relationship, - env.timeZone - ) - .build(); + var update = new TripUpdateBuilder(TRIP_1_ID, SERVICE_DATE, relationship, env.timeZone).build(); assertSuccess(env.applyTripUpdate(update)); var snapshot = env.getTimetableSnapshot(); - var forToday = snapshot.resolve(pattern1, RealtimeTestEnvironment.SERVICE_DATE); + var forToday = snapshot.resolve(pattern1, SERVICE_DATE); var schedule = snapshot.resolve(pattern1, null); assertNotSame(forToday, schedule); assertNotSame(forToday.getTripTimes(tripIndex1), schedule.getTripTimes(tripIndex1)); @@ -76,7 +72,7 @@ void cancelingAddedTrip(ScheduleRelationship relationship, RealTimeState state) // First add ADDED trip var update = new TripUpdateBuilder( addedTripId, - RealtimeTestEnvironment.SERVICE_DATE, + SERVICE_DATE, ScheduleRelationship.ADDED, env.timeZone ) @@ -88,14 +84,7 @@ void cancelingAddedTrip(ScheduleRelationship relationship, RealTimeState state) assertSuccess(env.applyTripUpdate(update, DIFFERENTIAL)); // Cancel or delete the added trip - update = - new TripUpdateBuilder( - addedTripId, - RealtimeTestEnvironment.SERVICE_DATE, - relationship, - env.timeZone - ) - .build(); + update = new TripUpdateBuilder(addedTripId, SERVICE_DATE, relationship, env.timeZone).build(); assertSuccess(env.applyTripUpdate(update, DIFFERENTIAL)); var snapshot = env.getTimetableSnapshot(); @@ -105,7 +94,7 @@ void cancelingAddedTrip(ScheduleRelationship relationship, RealTimeState state) assertNotNull(patternsAtA, "Added trip pattern should be found"); var tripPattern = patternsAtA.stream().findFirst().get(); - var forToday = snapshot.resolve(tripPattern, RealtimeTestEnvironment.SERVICE_DATE); + var forToday = snapshot.resolve(tripPattern, SERVICE_DATE); var schedule = snapshot.resolve(tripPattern, null); assertNotSame(forToday, schedule); diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java index 5298853f36d..cf921f39cd7 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java @@ -28,7 +28,7 @@ void singleStopDelay() { var env = RealtimeTestEnvironment.gtfs(); var tripUpdate = new TripUpdateBuilder( - env.trip1.getId().getId(), + RealtimeTestEnvironment.TRIP_1_ID, RealtimeTestEnvironment.SERVICE_DATE, SCHEDULED, env.timeZone @@ -40,8 +40,8 @@ void singleStopDelay() { assertEquals(1, result.successful()); - var pattern1 = env.getPatternForTrip(env.trip1); - int trip1Index = pattern1.getScheduledTimetable().getTripIndex(env.trip1.getId()); + var pattern1 = env.getPatternForTrip(env.trip1()); + int trip1Index = pattern1.getScheduledTimetable().getTripIndex(env.trip1().getId()); var snapshot = env.getTimetableSnapshot(); var trip1Realtime = snapshot.resolve(pattern1, RealtimeTestEnvironment.SERVICE_DATE); @@ -59,11 +59,11 @@ void singleStopDelay() { assertEquals( "SCHEDULED | A1 0:00:10 0:00:11 | B1 0:00:20 0:00:21", - env.getScheduledTimetable(env.trip1.getId()) + env.getScheduledTimetable(env.trip1().getId()) ); assertEquals( "UPDATED | A1 [ND] 0:00:10 0:00:11 | B1 0:00:21 0:00:22", - env.getRealtimeTimetable(env.trip1.getId().getId()) + env.getRealtimeTimetable(RealtimeTestEnvironment.TRIP_1_ID) ); } @@ -74,7 +74,7 @@ void singleStopDelay() { void complexDelay() { var env = RealtimeTestEnvironment.gtfs(); - var tripId = env.trip2.getId().getId(); + var tripId = RealtimeTestEnvironment.TRIP_2_ID; var tripUpdate = new TripUpdateBuilder(tripId, SERVICE_DATE, SCHEDULED, env.timeZone) .addDelayedStopTime(0, 0) @@ -86,7 +86,7 @@ void complexDelay() { var snapshot = env.getTimetableSnapshot(); - final TripPattern originalTripPattern = env.getTransitService().getPatternForTrip(env.trip2); + final TripPattern originalTripPattern = env.getTransitService().getPatternForTrip(env.trip2()); var originalTimetableForToday = snapshot.resolve(originalTripPattern, SERVICE_DATE); var originalTimetableScheduled = snapshot.resolve(originalTripPattern, null); @@ -115,11 +115,11 @@ void complexDelay() { assertEquals( "SCHEDULED | A1 0:01 0:01:01 | B1 0:01:10 0:01:11 | C1 0:01:20 0:01:21", - env.getScheduledTimetable(env.trip2.getId()) + env.getScheduledTimetable(env.trip2().getId()) ); assertEquals( "UPDATED | A1 0:01 0:01:01 | B1 0:02:10 0:02:31 | C1 0:02:50 0:02:51", - env.getRealtimeTimetable(env.trip2) + env.getRealtimeTimetable(env.trip2()) ); } } diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java index de699324bb6..8d62b691108 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java @@ -8,6 +8,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertSuccess; import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.SERVICE_DATE; +import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.TRIP_2_ID; import static org.opentripplanner.updater.trip.UpdateIncrementality.DIFFERENTIAL; import org.junit.jupiter.api.Test; @@ -25,9 +26,8 @@ public class SkippedTest { @Test void scheduledTripWithSkippedAndScheduled() { var env = RealtimeTestEnvironment.gtfs(); - String scheduledTripId = env.trip2.getId().getId(); - var tripUpdate = new TripUpdateBuilder(scheduledTripId, SERVICE_DATE, SCHEDULED, env.timeZone) + var tripUpdate = new TripUpdateBuilder(TRIP_2_ID, SERVICE_DATE, SCHEDULED, env.timeZone) .addDelayedStopTime(0, 0) .addSkippedStop(1) .addDelayedStopTime(2, 90) @@ -35,13 +35,13 @@ void scheduledTripWithSkippedAndScheduled() { assertSuccess(env.applyTripUpdate(tripUpdate)); - assertOriginalTripPatternIsDeleted(env, env.trip2.getId()); + assertOriginalTripPatternIsDeleted(env, env.trip2().getId()); - assertNewTripTimesIsUpdated(env, env.trip2.getId()); + assertNewTripTimesIsUpdated(env, env.trip2().getId()); assertEquals( "UPDATED | A1 0:01 0:01:01 | B1 [C] 0:01:52 0:01:58 | C1 0:02:50 0:02:51", - env.getRealtimeTimetable(scheduledTripId) + env.getRealtimeTimetable(TRIP_2_ID) ); } @@ -57,7 +57,7 @@ void scheduledTripWithSkippedAndScheduled() { @Test void scheduledTripWithPreviouslySkipped() { var env = RealtimeTestEnvironment.gtfs(); - var tripId = env.trip2.getId(); + var tripId = env.trip2().getId(); var tripUpdate = new TripUpdateBuilder(tripId.getId(), SERVICE_DATE, SCHEDULED, env.timeZone) .addDelayedStopTime(0, 0) @@ -108,7 +108,7 @@ void scheduledTripWithPreviouslySkipped() { void skippedNoData() { var env = RealtimeTestEnvironment.gtfs(); - final FeedScopedId tripId = env.trip2.getId(); + final FeedScopedId tripId = env.trip2().getId(); var tripUpdate = new TripUpdateBuilder(tripId.getId(), SERVICE_DATE, SCHEDULED, env.timeZone) .addNoDataStop(0) @@ -124,7 +124,7 @@ void skippedNoData() { assertEquals( "UPDATED | A1 [ND] 0:01 0:01:01 | B1 [C] 0:01:10 0:01:11 | C1 [ND] 0:01:20 0:01:21", - env.getRealtimeTimetable(env.trip2) + env.getRealtimeTimetable(env.trip2()) ); } @@ -178,7 +178,7 @@ private static void assertNewTripTimesIsUpdated( RealtimeTestEnvironment env, FeedScopedId tripId ) { - var originalTripPattern = env.getTransitService().getPatternForTrip(env.trip2); + var originalTripPattern = env.getTransitService().getPatternForTrip(env.trip2()); var snapshot = env.getTimetableSnapshot(); var originalTimetableForToday = snapshot.resolve(originalTripPattern, SERVICE_DATE); diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java index da362451753..d90aecc821d 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java @@ -5,6 +5,7 @@ import static org.opentripplanner.updater.spi.UpdateError.UpdateErrorType.NO_SERVICE_ON_DATE; import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertFailure; import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.SERVICE_DATE; +import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.TRIP_1_ID; import java.time.LocalDate; import java.util.List; @@ -26,9 +27,9 @@ public static List cases() { @ParameterizedTest @MethodSource("cases") void invalidTripDate(LocalDate date) { - var env = RealtimeTestEnvironment.gtfs(); + var env = RealtimeTestEnvironment.gtfs().withTrip1(); - var update = new TripUpdateBuilder(env.trip1.getId().getId(), date, SCHEDULED, env.timeZone) + var update = new TripUpdateBuilder(TRIP_1_ID, date, SCHEDULED, env.timeZone) .addDelayedStopTime(2, 60, 80) .build(); From a2b7f48c853cf5afda972e826f6d9c9e7d400724 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 8 Jul 2024 16:02:57 +0200 Subject: [PATCH 02/47] Introduce builder for test environment --- .../siri/SiriTimetableSnapshotSourceTest.java | 58 ++++++++++--------- .../updater/trip/RealtimeTestEnvironment.java | 27 +++++---- .../trip/RealtimeTestEnvironmentBuilder.java | 30 ++++++++++ .../trip/moduletests/addition/AddedTest.java | 8 +-- .../CancellationDeletionTest.java | 4 +- .../trip/moduletests/delay/DelayedTest.java | 4 +- .../trip/moduletests/delay/SkippedTest.java | 6 +- .../rejection/InvalidInputTest.java | 2 +- .../rejection/InvalidTripIdTest.java | 2 +- 9 files changed, 88 insertions(+), 53 deletions(-) create mode 100644 src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java index ea94d4b9505..136c68bc62a 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java @@ -4,6 +4,8 @@ import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertFailure; import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.OPERATOR_1_ID; import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.ROUTE_1_ID; +import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.TRIP_1_ID; +import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.TRIP_2_ID; import java.util.Set; import org.junit.jupiter.api.Disabled; @@ -16,12 +18,12 @@ class SiriTimetableSnapshotSourceTest { @Test void testCancelTrip() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().withTrip1().build(); assertEquals(RealTimeState.SCHEDULED, env.getTripTimesForTrip(env.trip1()).getRealTimeState()); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(RealtimeTestEnvironment.TRIP_1_ID) + .withDatedVehicleJourneyRef(TRIP_1_ID) .withCancellation(true) .buildEstimatedTimetableDeliveries(); @@ -33,7 +35,7 @@ void testCancelTrip() { @Test void testAddJourney() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().withTrip1().build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withEstimatedVehicleJourneyCode("newJourney") @@ -56,7 +58,7 @@ void testAddJourney() { @Test void testAddedJourneyWithInvalidScheduledData() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().withTrip1().build(); // Create an extra journey with invalid planned data (travel back in time) // and valid real time data @@ -105,13 +107,13 @@ void testAddedJourneyWithUnresolvableAgency() { @Test void testReplaceJourney() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().withTrip1().build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withEstimatedVehicleJourneyCode("newJourney") .withIsExtraJourney(true) // replace trip1 - .withVehicleJourneyRef(RealtimeTestEnvironment.TRIP_1_ID) + .withVehicleJourneyRef(TRIP_1_ID) .withOperatorRef(OPERATOR_1_ID) .withLineRef(ROUTE_1_ID) .withRecordedCalls(builder -> builder.call(env.stopA1).departAimedActual("00:01", "00:02")) @@ -138,10 +140,10 @@ void testReplaceJourney() { */ @Test void testUpdateJourneyWithDatedVehicleJourneyRef() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().withTrip1().build(); var updates = updatedJourneyBuilder(env) - .withDatedVehicleJourneyRef(RealtimeTestEnvironment.TRIP_1_ID) + .withDatedVehicleJourneyRef(TRIP_1_ID) .buildEstimatedTimetableDeliveries(); var result = env.applyEstimatedTimetable(updates); assertEquals(1, result.successful()); @@ -157,13 +159,13 @@ void testUpdateJourneyWithDatedVehicleJourneyRef() { */ @Test void testUpdateJourneyWithFramedVehicleJourneyRef() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().withTrip1().build(); var updates = updatedJourneyBuilder(env) .withFramedVehicleJourneyRef(builder -> builder .withServiceDate(RealtimeTestEnvironment.SERVICE_DATE) - .withVehicleJourneyRef(RealtimeTestEnvironment.TRIP_1_ID) + .withVehicleJourneyRef(TRIP_1_ID) ) .buildEstimatedTimetableDeliveries(); var result = env.applyEstimatedTimetable(updates); @@ -176,7 +178,7 @@ void testUpdateJourneyWithFramedVehicleJourneyRef() { */ @Test void testUpdateJourneyWithoutJourneyRef() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().withTrip1().build(); var updates = updatedJourneyBuilder(env).buildEstimatedTimetableDeliveries(); var result = env.applyEstimatedTimetable(updates); @@ -189,7 +191,7 @@ void testUpdateJourneyWithoutJourneyRef() { */ @Test void testUpdateJourneyWithFuzzyMatching() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().withTrip1().build(); var updates = updatedJourneyBuilder(env).buildEstimatedTimetableDeliveries(); var result = env.applyEstimatedTimetableWithFuzzyMatcher(updates); @@ -203,7 +205,7 @@ void testUpdateJourneyWithFuzzyMatching() { */ @Test void testUpdateJourneyWithFuzzyMatchingAndMissingAimedDepartureTime() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().withTrip1().build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withFramedVehicleJourneyRef(builder -> @@ -228,10 +230,10 @@ void testUpdateJourneyWithFuzzyMatchingAndMissingAimedDepartureTime() { */ @Test void testChangeQuay() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().withTrip1().build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(RealtimeTestEnvironment.TRIP_1_ID) + .withDatedVehicleJourneyRef(TRIP_1_ID) .withRecordedCalls(builder -> builder.call(env.stopA1).departAimedActual("00:00:11", "00:00:15") ) @@ -251,10 +253,10 @@ void testChangeQuay() { @Test void testCancelStop() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().withTrip2().build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(env.trip2().getId().getId()) + .withDatedVehicleJourneyRef(TRIP_2_ID) .withEstimatedCalls(builder -> builder .call(env.stopA1) @@ -279,10 +281,10 @@ void testCancelStop() { @Test @Disabled("Not supported yet") void testAddStop() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().withTrip1().build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(RealtimeTestEnvironment.TRIP_1_ID) + .withDatedVehicleJourneyRef(TRIP_1_ID) .withRecordedCalls(builder -> builder.call(env.stopA1).departAimedActual("00:00:11", "00:00:15") ) @@ -312,7 +314,7 @@ void testAddStop() { @Test void testNotMonitored() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().withTrip1().build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withMonitored(false) @@ -325,12 +327,12 @@ void testNotMonitored() { @Test void testReplaceJourneyWithoutEstimatedVehicleJourneyCode() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().withTrip1().build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withDatedVehicleJourneyRef("newJourney") .withIsExtraJourney(true) - .withVehicleJourneyRef(RealtimeTestEnvironment.TRIP_1_ID) + .withVehicleJourneyRef(TRIP_1_ID) .withOperatorRef(OPERATOR_1_ID) .withLineRef(ROUTE_1_ID) .withEstimatedCalls(builder -> @@ -350,10 +352,10 @@ void testReplaceJourneyWithoutEstimatedVehicleJourneyCode() { @Test void testNegativeHopTime() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().withTrip1().build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(RealtimeTestEnvironment.TRIP_1_ID) + .withDatedVehicleJourneyRef(TRIP_1_ID) .withRecordedCalls(builder -> builder .call(env.stopA1) @@ -370,10 +372,10 @@ void testNegativeHopTime() { @Test void testNegativeDwellTime() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().withTrip2().build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(env.trip2().getId().getId()) + .withDatedVehicleJourneyRef(TRIP_2_ID) .withRecordedCalls(builder -> builder .call(env.stopA1) @@ -395,10 +397,10 @@ void testNegativeDwellTime() { @Test @Disabled("Not supported yet") void testExtraUnknownStop() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().withTrip1().build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) - .withDatedVehicleJourneyRef(RealtimeTestEnvironment.TRIP_1_ID) + .withDatedVehicleJourneyRef(TRIP_1_ID) .withEstimatedCalls(builder -> builder .call(env.stopA1) diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java index ba26ed97f79..7e8ca135e41 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java @@ -96,7 +96,7 @@ public final class RealtimeTestEnvironment { private Trip trip1; private Trip trip2; - private enum SourceType { + enum SourceType { GTFS_RT, SIRI, } @@ -104,25 +104,22 @@ private enum SourceType { /** * Siri and GTFS-RT cannot be run at the same time, so you need to decide. */ - public static RealtimeTestEnvironment siri() { - return new RealtimeTestEnvironment(SourceType.SIRI); + public static RealtimeTestEnvironmentBuilder siri() { + return new RealtimeTestEnvironmentBuilder().withSourceType(SourceType.SIRI); } /** * Siri and GTFS-RT cannot be run at the same time, so you need to decide. */ - public static RealtimeTestEnvironment gtfs() { - return new RealtimeTestEnvironment(SourceType.GTFS_RT); + public static RealtimeTestEnvironmentBuilder gtfs() { + return new RealtimeTestEnvironmentBuilder().withSourceType(SourceType.GTFS_RT); } - private RealtimeTestEnvironment(SourceType sourceType) { + RealtimeTestEnvironment(SourceType sourceType, boolean withTrip1, boolean withTrip2) { transitModel = new TransitModel(stopModel, new Deduplicator()); transitModel.initTimeZone(timeZone); transitModel.addAgency(TransitModelForTest.AGENCY); - withTrip1(); - withTrip2(); - CalendarServiceData calendarServiceData = new CalendarServiceData(); calendarServiceData.putServiceDatesForServiceId( SERVICE_ID, @@ -131,8 +128,14 @@ private RealtimeTestEnvironment(SourceType sourceType) { transitModel.getServiceCodes().put(SERVICE_ID, 0); transitModel.updateCalendarServiceData(true, calendarServiceData, DataImportIssueStore.NOOP); - transitModel.index(); + if (withTrip1) { + withTrip1(); + } + if (withTrip2) { + withTrip2(); + } + transitModel.index(); // SIRI and GTFS-RT cannot be registered with the transit model at the same time // we are actively refactoring to remove this restriction // for the time being you cannot run a SIRI and GTFS-RT test at the same time @@ -146,7 +149,7 @@ private RealtimeTestEnvironment(SourceType sourceType) { dateTimeHelper = new DateTimeHelper(timeZone, RealtimeTestEnvironment.SERVICE_DATE); } - public RealtimeTestEnvironment withTrip1() { + private RealtimeTestEnvironment withTrip1() { trip1 = createTrip( TRIP_1_ID, @@ -157,7 +160,7 @@ public RealtimeTestEnvironment withTrip1() { return this; } - public RealtimeTestEnvironment withTrip2() { + private RealtimeTestEnvironment withTrip2() { trip2 = createTrip( TRIP_2_ID, diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java new file mode 100644 index 00000000000..ff15c845742 --- /dev/null +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java @@ -0,0 +1,30 @@ +package org.opentripplanner.updater.trip; + +import java.util.Objects; + +public class RealtimeTestEnvironmentBuilder { + + private RealtimeTestEnvironment.SourceType sourceType; + private boolean withTrip1 = false; + private boolean withTrip2 = false; + + RealtimeTestEnvironmentBuilder withSourceType(RealtimeTestEnvironment.SourceType sourceType) { + this.sourceType = sourceType; + return this; + } + + public RealtimeTestEnvironmentBuilder withTrip1() { + withTrip1 = true; + return this; + } + + public RealtimeTestEnvironmentBuilder withTrip2() { + withTrip2 = true; + return this; + } + + public RealtimeTestEnvironment build() { + Objects.requireNonNull(sourceType, "sourceType cannot be null"); + return new RealtimeTestEnvironment(sourceType, withTrip1, withTrip2); + } +} diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/addition/AddedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/addition/AddedTest.java index 8371c5dda3a..cc02715b4e0 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/addition/AddedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/addition/AddedTest.java @@ -29,7 +29,7 @@ class AddedTest { @Test void addedTrip() { - var env = RealtimeTestEnvironment.gtfs(); + var env = RealtimeTestEnvironment.gtfs().build(); var tripUpdate = new TripUpdateBuilder(ADDED_TRIP_ID, SERVICE_DATE, ADDED, env.timeZone) .addStopTime(STOP_A1_ID, 30) @@ -43,7 +43,7 @@ void addedTrip() { @Test void addedTripWithNewRoute() { - var env = RealtimeTestEnvironment.gtfs(); + var env = RealtimeTestEnvironment.gtfs().build(); var tripUpdate = new TripUpdateBuilder(ADDED_TRIP_ID, SERVICE_DATE, ADDED, env.timeZone) .addTripExtension() .addStopTime(STOP_A1_ID, 30, DropOffPickupType.PHONE_AGENCY) @@ -74,7 +74,7 @@ void addedTripWithNewRoute() { @Test void addedWithUnknownStop() { - var env = RealtimeTestEnvironment.gtfs(); + var env = RealtimeTestEnvironment.gtfs().build(); var tripUpdate = new TripUpdateBuilder(ADDED_TRIP_ID, SERVICE_DATE, ADDED, env.timeZone) // add extension to set route name, url, mode .addTripExtension() @@ -98,7 +98,7 @@ void addedWithUnknownStop() { @Test void repeatedlyAddedTripWithNewRoute() { - var env = RealtimeTestEnvironment.gtfs(); + var env = RealtimeTestEnvironment.gtfs().build(); var tripUpdate = new TripUpdateBuilder(ADDED_TRIP_ID, SERVICE_DATE, ADDED, env.timeZone) // add extension to set route name, url, mode .addTripExtension() diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java index 57d48fa9db3..00344744600 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java @@ -34,7 +34,7 @@ static List cases() { @ParameterizedTest @MethodSource("cases") void cancelledTrip(ScheduleRelationship relationship, RealTimeState state) { - var env = RealtimeTestEnvironment.gtfs().withTrip1(); + var env = RealtimeTestEnvironment.gtfs().withTrip1().build(); var pattern1 = env.getPatternForTrip(env.trip1()); final int tripIndex1 = pattern1.getScheduledTimetable().getTripIndex(env.trip1().getId()); @@ -67,7 +67,7 @@ void cancelledTrip(ScheduleRelationship relationship, RealTimeState state) { @ParameterizedTest @MethodSource("cases") void cancelingAddedTrip(ScheduleRelationship relationship, RealTimeState state) { - var env = RealtimeTestEnvironment.gtfs(); + var env = RealtimeTestEnvironment.gtfs().withTrip1().build(); var addedTripId = "added-trip"; // First add ADDED trip var update = new TripUpdateBuilder( diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java index cf921f39cd7..d1058151dcf 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java @@ -25,7 +25,7 @@ class DelayedTest { @Test void singleStopDelay() { - var env = RealtimeTestEnvironment.gtfs(); + var env = RealtimeTestEnvironment.gtfs().withTrip1().build(); var tripUpdate = new TripUpdateBuilder( RealtimeTestEnvironment.TRIP_1_ID, @@ -72,7 +72,7 @@ void singleStopDelay() { */ @Test void complexDelay() { - var env = RealtimeTestEnvironment.gtfs(); + var env = RealtimeTestEnvironment.gtfs().withTrip2().build(); var tripId = RealtimeTestEnvironment.TRIP_2_ID; diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java index 8d62b691108..f47463a46dc 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java @@ -25,7 +25,7 @@ public class SkippedTest { @Test void scheduledTripWithSkippedAndScheduled() { - var env = RealtimeTestEnvironment.gtfs(); + var env = RealtimeTestEnvironment.gtfs().withTrip2().build(); var tripUpdate = new TripUpdateBuilder(TRIP_2_ID, SERVICE_DATE, SCHEDULED, env.timeZone) .addDelayedStopTime(0, 0) @@ -56,7 +56,7 @@ void scheduledTripWithSkippedAndScheduled() { */ @Test void scheduledTripWithPreviouslySkipped() { - var env = RealtimeTestEnvironment.gtfs(); + var env = RealtimeTestEnvironment.gtfs().withTrip2().build(); var tripId = env.trip2().getId(); var tripUpdate = new TripUpdateBuilder(tripId.getId(), SERVICE_DATE, SCHEDULED, env.timeZone) @@ -106,7 +106,7 @@ void scheduledTripWithPreviouslySkipped() { */ @Test void skippedNoData() { - var env = RealtimeTestEnvironment.gtfs(); + var env = RealtimeTestEnvironment.gtfs().withTrip2().build(); final FeedScopedId tripId = env.trip2().getId(); diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java index d90aecc821d..b1bd5823592 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java @@ -27,7 +27,7 @@ public static List cases() { @ParameterizedTest @MethodSource("cases") void invalidTripDate(LocalDate date) { - var env = RealtimeTestEnvironment.gtfs().withTrip1(); + var env = RealtimeTestEnvironment.gtfs().withTrip1().build(); var update = new TripUpdateBuilder(TRIP_1_ID, date, SCHEDULED, env.timeZone) .addDelayedStopTime(2, 60, 80) diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidTripIdTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidTripIdTest.java index 83c2547dbc7..bb723d4acab 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidTripIdTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidTripIdTest.java @@ -22,7 +22,7 @@ static Stream invalidCases() { @ParameterizedTest(name = "tripId=\"{0}\"") @MethodSource("invalidCases") void invalidTripId(String tripId) { - var env = RealtimeTestEnvironment.gtfs(); + var env = RealtimeTestEnvironment.gtfs().withTrip1().build(); var tripDescriptorBuilder = GtfsRealtime.TripDescriptor.newBuilder(); if (tripId != null) { tripDescriptorBuilder.setTripId(tripId); From 9d68130cf64b29fc8ed03f227a9b984594e7f81d Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 4 Sep 2024 11:27:18 +0200 Subject: [PATCH 03/47] Extract test constants into separate interface --- .../siri/SiriTimetableSnapshotSourceTest.java | 75 +++++++++---------- .../updater/trip/RealtimeTestConstants.java | 44 +++++++++++ .../updater/trip/RealtimeTestEnvironment.java | 51 ++----------- .../trip/moduletests/addition/AddedTest.java | 17 ++--- .../CancellationDeletionTest.java | 19 +++-- .../trip/moduletests/delay/DelayedTest.java | 8 +- .../trip/moduletests/delay/SkippedTest.java | 8 +- .../rejection/InvalidInputTest.java | 2 +- 8 files changed, 111 insertions(+), 113 deletions(-) create mode 100644 src/test/java/org/opentripplanner/updater/trip/RealtimeTestConstants.java diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java index 136c68bc62a..d77e561f0e7 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java @@ -2,19 +2,15 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertFailure; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.OPERATOR_1_ID; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.ROUTE_1_ID; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.TRIP_1_ID; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.TRIP_2_ID; -import java.util.Set; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.opentripplanner.transit.model.timetable.RealTimeState; import org.opentripplanner.updater.spi.UpdateError; +import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; -class SiriTimetableSnapshotSourceTest { +class SiriTimetableSnapshotSourceTest implements RealtimeTestConstants { @Test void testCancelTrip() { @@ -42,8 +38,8 @@ void testAddJourney() { .withIsExtraJourney(true) .withOperatorRef(OPERATOR_1_ID) .withLineRef(ROUTE_1_ID) - .withRecordedCalls(builder -> builder.call(env.stopC1).departAimedActual("00:01", "00:02")) - .withEstimatedCalls(builder -> builder.call(env.stopD1).arriveAimedExpected("00:03", "00:04")) + .withRecordedCalls(builder -> builder.call(STOP_C1).departAimedActual("00:01", "00:02")) + .withEstimatedCalls(builder -> builder.call(STOP_D1).arriveAimedExpected("00:03", "00:04")) .buildEstimatedTimetableDeliveries(); var result = env.applyEstimatedTimetable(updates); @@ -69,9 +65,9 @@ void testAddedJourneyWithInvalidScheduledData() { .withLineRef(ROUTE_1_ID) .withEstimatedCalls(builder -> builder - .call(env.stopA1) + .call(STOP_A1) .departAimedExpected("10:58", "10:48") - .call(env.stopB1) + .call(STOP_B1) .arriveAimedExpected("10:08", "10:58") ) .buildEstimatedTimetableDeliveries(); @@ -83,7 +79,7 @@ void testAddedJourneyWithInvalidScheduledData() { @Test void testAddedJourneyWithUnresolvableAgency() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().build(); // Create an extra journey with unknown line and operator var createExtraJourney = new SiriEtBuilder(env.getDateTimeHelper()) @@ -93,9 +89,9 @@ void testAddedJourneyWithUnresolvableAgency() { .withLineRef("unknown line") .withEstimatedCalls(builder -> builder - .call(env.stopA1) + .call(STOP_A1) .departAimedExpected("10:58", "10:48") - .call(env.stopB1) + .call(STOP_B1) .arriveAimedExpected("10:08", "10:58") ) .buildEstimatedTimetableDeliveries(); @@ -116,8 +112,9 @@ void testReplaceJourney() { .withVehicleJourneyRef(TRIP_1_ID) .withOperatorRef(OPERATOR_1_ID) .withLineRef(ROUTE_1_ID) - .withRecordedCalls(builder -> builder.call(env.stopA1).departAimedActual("00:01", "00:02")) - .withEstimatedCalls(builder -> builder.call(env.stopC1).arriveAimedExpected("00:03", "00:04")) + .withRecordedCalls(builder -> builder.call(STOP_A1).departAimedActual("00:01", "00:02")) + .withEstimatedCalls(builder -> builder.call(env.STOP_C1).arriveAimedExpected("00:03", "00:04") + ) .buildEstimatedTimetableDeliveries(); var result = env.applyEstimatedTimetable(updates); @@ -213,9 +210,9 @@ void testUpdateJourneyWithFuzzyMatchingAndMissingAimedDepartureTime() { ) .withEstimatedCalls(builder -> builder - .call(env.stopA1) + .call(STOP_A1) .departAimedExpected(null, "00:00:12") - .call(env.stopB1) + .call(env.STOP_B1) .arriveAimedExpected("00:00:20", "00:00:22") ) .buildEstimatedTimetableDeliveries(); @@ -234,11 +231,9 @@ void testChangeQuay() { var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withDatedVehicleJourneyRef(TRIP_1_ID) - .withRecordedCalls(builder -> - builder.call(env.stopA1).departAimedActual("00:00:11", "00:00:15") - ) + .withRecordedCalls(builder -> builder.call(STOP_A1).departAimedActual("00:00:11", "00:00:15")) .withEstimatedCalls(builder -> - builder.call(env.stopB2).arriveAimedExpected("00:00:20", "00:00:33") + builder.call(env.STOP_B2).arriveAimedExpected("00:00:20", "00:00:33") ) .buildEstimatedTimetableDeliveries(); @@ -259,11 +254,11 @@ void testCancelStop() { .withDatedVehicleJourneyRef(TRIP_2_ID) .withEstimatedCalls(builder -> builder - .call(env.stopA1) + .call(STOP_A1) .departAimedExpected("00:01:01", "00:01:01") - .call(env.stopB1) + .call(env.STOP_B1) .withIsCancellation(true) - .call(env.stopC1) + .call(env.STOP_C1) .arriveAimedExpected("00:01:30", "00:01:30") ) .buildEstimatedTimetableDeliveries(); @@ -285,16 +280,14 @@ void testAddStop() { var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withDatedVehicleJourneyRef(TRIP_1_ID) - .withRecordedCalls(builder -> - builder.call(env.stopA1).departAimedActual("00:00:11", "00:00:15") - ) + .withRecordedCalls(builder -> builder.call(STOP_A1).departAimedActual("00:00:11", "00:00:15")) .withEstimatedCalls(builder -> builder - .call(env.stopD1) + .call(env.STOP_D1) .withIsExtraCall(true) .arriveAimedExpected("00:00:19", "00:00:20") .departAimedExpected("00:00:24", "00:00:25") - .call(env.stopB1) + .call(env.STOP_B1) .arriveAimedExpected("00:00:20", "00:00:33") ) .buildEstimatedTimetableDeliveries(); @@ -337,9 +330,9 @@ void testReplaceJourneyWithoutEstimatedVehicleJourneyCode() { .withLineRef(ROUTE_1_ID) .withEstimatedCalls(builder -> builder - .call(env.stopA1) + .call(STOP_A1) .departAimedExpected("00:01", "00:02") - .call(env.stopC1) + .call(env.STOP_C1) .arriveAimedExpected("00:03", "00:04") ) .buildEstimatedTimetableDeliveries(); @@ -358,9 +351,9 @@ void testNegativeHopTime() { .withDatedVehicleJourneyRef(TRIP_1_ID) .withRecordedCalls(builder -> builder - .call(env.stopA1) + .call(STOP_A1) .departAimedActual("00:00:11", "00:00:15") - .call(env.stopB1) + .call(env.STOP_B1) .arriveAimedActual("00:00:20", "00:00:14") ) .buildEstimatedTimetableDeliveries(); @@ -378,12 +371,12 @@ void testNegativeDwellTime() { .withDatedVehicleJourneyRef(TRIP_2_ID) .withRecordedCalls(builder -> builder - .call(env.stopA1) + .call(STOP_A1) .departAimedActual("00:01:01", "00:01:01") - .call(env.stopB1) + .call(STOP_B1) .arriveAimedActual("00:01:10", "00:01:13") .departAimedActual("00:01:11", "00:01:12") - .call(env.stopB1) + .call(STOP_B1) .arriveAimedActual("00:01:20", "00:01:20") ) .buildEstimatedTimetableDeliveries(); @@ -403,13 +396,13 @@ void testExtraUnknownStop() { .withDatedVehicleJourneyRef(TRIP_1_ID) .withEstimatedCalls(builder -> builder - .call(env.stopA1) + .call(STOP_A1) .departAimedExpected("00:00:11", "00:00:15") // Unexpected extra stop without isExtraCall flag - .call(env.stopD1) + .call(STOP_D1) .arriveAimedExpected("00:00:19", "00:00:20") .departAimedExpected("00:00:24", "00:00:25") - .call(env.stopB1) + .call(STOP_B1) .arriveAimedExpected("00:00:20", "00:00:33") ) .buildEstimatedTimetableDeliveries(); @@ -423,9 +416,9 @@ private static SiriEtBuilder updatedJourneyBuilder(RealtimeTestEnvironment env) return new SiriEtBuilder(env.getDateTimeHelper()) .withEstimatedCalls(builder -> builder - .call(env.stopA1) + .call(STOP_A1) .departAimedExpected("00:00:11", "00:00:15") - .call(env.stopB1) + .call(STOP_B1) .arriveAimedExpected("00:00:20", "00:00:25") ); } diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestConstants.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestConstants.java new file mode 100644 index 00000000000..cc9252bda6d --- /dev/null +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestConstants.java @@ -0,0 +1,44 @@ +package org.opentripplanner.updater.trip; + +import java.time.LocalDate; +import java.time.ZoneId; +import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.network.Route; +import org.opentripplanner.transit.model.site.RegularStop; +import org.opentripplanner.transit.model.site.Station; +import org.opentripplanner.transit.service.StopModel; + +public interface RealtimeTestConstants { + LocalDate SERVICE_DATE = LocalDate.of(2024, 5, 8); + FeedScopedId SERVICE_ID = TransitModelForTest.id("CAL_1"); + String STOP_A1_ID = "A1"; + String STOP_B1_ID = "B1"; + String STOP_C1_ID = "C1"; + String TRIP_1_ID = "TestTrip1"; + String TRIP_2_ID = "TestTrip2"; + String OPERATOR_1_ID = "TestOperator1"; + String ROUTE_1_ID = "TestRoute1"; + + TransitModelForTest testModel = TransitModelForTest.of(); + ZoneId TIME_ZONE = ZoneId.of(TransitModelForTest.TIME_ZONE_ID); + Station STATION_A = testModel.station("A").build(); + Station stationB = testModel.station("B").build(); + Station stationC = testModel.station("C").build(); + Station stationD = testModel.station("D").build(); + RegularStop STOP_A1 = testModel.stop(STOP_A1_ID).withParentStation(STATION_A).build(); + RegularStop STOP_B1 = testModel.stop(STOP_B1_ID).withParentStation(stationB).build(); + RegularStop STOP_B2 = testModel.stop("B2").withParentStation(stationB).build(); + RegularStop STOP_C1 = testModel.stop(STOP_C1_ID).withParentStation(stationC).build(); + RegularStop STOP_D1 = testModel.stop("D1").withParentStation(stationD).build(); + StopModel STOP_MODEL = testModel + .stopModelBuilder() + .withRegularStop(STOP_A1) + .withRegularStop(STOP_B1) + .withRegularStop(STOP_B2) + .withRegularStop(STOP_C1) + .withRegularStop(STOP_D1) + .build(); + + Route route1 = TransitModelForTest.route(ROUTE_1_ID).build(); +} diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java index 7e8ca135e41..62eed418553 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java @@ -6,7 +6,6 @@ import com.google.transit.realtime.GtfsRealtime; import java.time.Duration; import java.time.LocalDate; -import java.time.ZoneId; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; @@ -26,7 +25,6 @@ import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.model.site.Station; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripOnServiceDate; @@ -34,7 +32,6 @@ import org.opentripplanner.transit.model.timetable.TripTimesFactory; import org.opentripplanner.transit.model.timetable.TripTimesStringBuilder; import org.opentripplanner.transit.service.DefaultTransitService; -import org.opentripplanner.transit.service.StopModel; import org.opentripplanner.transit.service.TransitModel; import org.opentripplanner.transit.service.TransitService; import org.opentripplanner.updater.TimetableSnapshotSourceParameters; @@ -48,45 +45,13 @@ *

* It is however a goal to change that and then these two can be combined. */ -public final class RealtimeTestEnvironment { +public final class RealtimeTestEnvironment implements RealtimeTestConstants { // static constants private static final TimetableSnapshotSourceParameters PARAMETERS = new TimetableSnapshotSourceParameters( Duration.ZERO, false ); - public static final LocalDate SERVICE_DATE = LocalDate.of(2024, 5, 8); - public static final FeedScopedId SERVICE_ID = TransitModelForTest.id("CAL_1"); - public static final String STOP_A1_ID = "A1"; - public static final String STOP_B1_ID = "B1"; - public static final String STOP_C1_ID = "C1"; - public static final String TRIP_1_ID = "TestTrip1"; - public static final String TRIP_2_ID = "TestTrip2"; - public static final String OPERATOR_1_ID = "TestOperator1"; - public static final String ROUTE_1_ID = "TestRoute1"; - - // instance variables - private final TransitModelForTest testModel = TransitModelForTest.of(); - public final ZoneId timeZone = ZoneId.of(TransitModelForTest.TIME_ZONE_ID); - public final Station stationA = testModel.station("A").build(); - public final Station stationB = testModel.station("B").build(); - public final Station stationC = testModel.station("C").build(); - public final Station stationD = testModel.station("D").build(); - public final RegularStop stopA1 = testModel.stop(STOP_A1_ID).withParentStation(stationA).build(); - public final RegularStop stopB1 = testModel.stop(STOP_B1_ID).withParentStation(stationB).build(); - public final RegularStop stopB2 = testModel.stop("B2").withParentStation(stationB).build(); - public final RegularStop stopC1 = testModel.stop(STOP_C1_ID).withParentStation(stationC).build(); - public final RegularStop stopD1 = testModel.stop("D1").withParentStation(stationD).build(); - public final StopModel stopModel = testModel - .stopModelBuilder() - .withRegularStop(stopA1) - .withRegularStop(stopB1) - .withRegularStop(stopB2) - .withRegularStop(stopC1) - .withRegularStop(stopD1) - .build(); - - public final Route route1 = TransitModelForTest.route(ROUTE_1_ID).build(); public final TransitModel transitModel; private final SiriTimetableSnapshotSource siriSource; @@ -116,8 +81,8 @@ public static RealtimeTestEnvironmentBuilder gtfs() { } RealtimeTestEnvironment(SourceType sourceType, boolean withTrip1, boolean withTrip2) { - transitModel = new TransitModel(stopModel, new Deduplicator()); - transitModel.initTimeZone(timeZone); + transitModel = new TransitModel(STOP_MODEL, new Deduplicator()); + transitModel.initTimeZone(TIME_ZONE); transitModel.addAgency(TransitModelForTest.AGENCY); CalendarServiceData calendarServiceData = new CalendarServiceData(); @@ -146,7 +111,7 @@ public static RealtimeTestEnvironmentBuilder gtfs() { gtfsSource = new TimetableSnapshotSource(PARAMETERS, transitModel); siriSource = null; } - dateTimeHelper = new DateTimeHelper(timeZone, RealtimeTestEnvironment.SERVICE_DATE); + dateTimeHelper = new DateTimeHelper(TIME_ZONE, RealtimeTestEnvironment.SERVICE_DATE); } private RealtimeTestEnvironment withTrip1() { @@ -154,7 +119,7 @@ private RealtimeTestEnvironment withTrip1() { createTrip( TRIP_1_ID, route1, - List.of(new StopCall(stopA1, 10, 11), new StopCall(stopB1, 20, 21)) + List.of(new StopCall(STOP_A1, 10, 11), new StopCall(STOP_B1, 20, 21)) ); transitModel.index(); return this; @@ -166,9 +131,9 @@ private RealtimeTestEnvironment withTrip2() { TRIP_2_ID, route1, List.of( - new StopCall(stopA1, 60, 61), - new StopCall(stopB1, 70, 71), - new StopCall(stopC1, 80, 81) + new StopCall(STOP_A1, 60, 61), + new StopCall(STOP_B1, 70, 71), + new StopCall(STOP_C1, 80, 81) ) ); diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/addition/AddedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/addition/AddedTest.java index cc02715b4e0..869c108839b 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/addition/AddedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/addition/AddedTest.java @@ -7,10 +7,6 @@ import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertSuccess; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.SERVICE_DATE; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.STOP_A1_ID; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.STOP_B1_ID; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.STOP_C1_ID; import de.mfdz.MfdzRealtimeExtensions.StopTimePropertiesExtension.DropOffPickupType; import java.util.List; @@ -20,10 +16,11 @@ import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.RealTimeState; import org.opentripplanner.updater.spi.UpdateSuccess; +import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; import org.opentripplanner.updater.trip.TripUpdateBuilder; -class AddedTest { +class AddedTest implements RealtimeTestConstants { final String ADDED_TRIP_ID = "added_trip"; @@ -31,7 +28,7 @@ class AddedTest { void addedTrip() { var env = RealtimeTestEnvironment.gtfs().build(); - var tripUpdate = new TripUpdateBuilder(ADDED_TRIP_ID, SERVICE_DATE, ADDED, env.timeZone) + var tripUpdate = new TripUpdateBuilder(ADDED_TRIP_ID, SERVICE_DATE, ADDED, TIME_ZONE) .addStopTime(STOP_A1_ID, 30) .addStopTime(STOP_B1_ID, 40) .addStopTime(STOP_C1_ID, 55) @@ -44,7 +41,7 @@ void addedTrip() { @Test void addedTripWithNewRoute() { var env = RealtimeTestEnvironment.gtfs().build(); - var tripUpdate = new TripUpdateBuilder(ADDED_TRIP_ID, SERVICE_DATE, ADDED, env.timeZone) + var tripUpdate = new TripUpdateBuilder(ADDED_TRIP_ID, SERVICE_DATE, ADDED, TIME_ZONE) .addTripExtension() .addStopTime(STOP_A1_ID, 30, DropOffPickupType.PHONE_AGENCY) .addStopTime(STOP_B1_ID, 40, DropOffPickupType.COORDINATE_WITH_DRIVER) @@ -75,7 +72,7 @@ void addedTripWithNewRoute() { @Test void addedWithUnknownStop() { var env = RealtimeTestEnvironment.gtfs().build(); - var tripUpdate = new TripUpdateBuilder(ADDED_TRIP_ID, SERVICE_DATE, ADDED, env.timeZone) + var tripUpdate = new TripUpdateBuilder(ADDED_TRIP_ID, SERVICE_DATE, ADDED, TIME_ZONE) // add extension to set route name, url, mode .addTripExtension() .addStopTime(STOP_A1_ID, 30, DropOffPickupType.PHONE_AGENCY) @@ -99,7 +96,7 @@ void addedWithUnknownStop() { @Test void repeatedlyAddedTripWithNewRoute() { var env = RealtimeTestEnvironment.gtfs().build(); - var tripUpdate = new TripUpdateBuilder(ADDED_TRIP_ID, SERVICE_DATE, ADDED, env.timeZone) + var tripUpdate = new TripUpdateBuilder(ADDED_TRIP_ID, SERVICE_DATE, ADDED, TIME_ZONE) // add extension to set route name, url, mode .addTripExtension() .addStopTime(STOP_A1_ID, 30, DropOffPickupType.PHONE_AGENCY) @@ -122,7 +119,7 @@ void repeatedlyAddedTripWithNewRoute() { private TripPattern assertAddedTrip(String tripId, RealtimeTestEnvironment env) { var snapshot = env.getTimetableSnapshot(); - var stopA = env.transitModel.getStopModel().getRegularStop(env.stopA1.getId()); + var stopA = env.transitModel.getStopModel().getRegularStop(STOP_A1.getId()); // Get the trip pattern of the added trip which goes through stopA var patternsAtA = env.getTimetableSnapshot().getPatternsForStop(stopA); diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java index 00344744600..eb304189e47 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java @@ -5,8 +5,6 @@ import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertSuccess; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.SERVICE_DATE; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.TRIP_1_ID; import static org.opentripplanner.updater.trip.UpdateIncrementality.DIFFERENTIAL; import com.google.transit.realtime.GtfsRealtime.TripDescriptor.ScheduleRelationship; @@ -15,6 +13,7 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.transit.model.timetable.RealTimeState; +import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; import org.opentripplanner.updater.trip.TripUpdateBuilder; @@ -22,7 +21,7 @@ * Cancellations and deletions should end up in the internal data model and make trips unavailable * for routing. */ -public class CancellationDeletionTest { +public class CancellationDeletionTest implements RealtimeTestConstants { static List cases() { return List.of( @@ -39,7 +38,7 @@ void cancelledTrip(ScheduleRelationship relationship, RealTimeState state) { final int tripIndex1 = pattern1.getScheduledTimetable().getTripIndex(env.trip1().getId()); - var update = new TripUpdateBuilder(TRIP_1_ID, SERVICE_DATE, relationship, env.timeZone).build(); + var update = new TripUpdateBuilder(TRIP_1_ID, SERVICE_DATE, relationship, TIME_ZONE).build(); assertSuccess(env.applyTripUpdate(update)); var snapshot = env.getTimetableSnapshot(); @@ -74,22 +73,22 @@ void cancelingAddedTrip(ScheduleRelationship relationship, RealTimeState state) addedTripId, SERVICE_DATE, ScheduleRelationship.ADDED, - env.timeZone + TIME_ZONE ) - .addStopTime(env.stopA1.getId().getId(), 30) - .addStopTime(env.stopB1.getId().getId(), 40) - .addStopTime(env.stopC1.getId().getId(), 55) + .addStopTime(STOP_A1.getId().getId(), 30) + .addStopTime(STOP_B1.getId().getId(), 40) + .addStopTime(STOP_C1.getId().getId(), 55) .build(); assertSuccess(env.applyTripUpdate(update, DIFFERENTIAL)); // Cancel or delete the added trip - update = new TripUpdateBuilder(addedTripId, SERVICE_DATE, relationship, env.timeZone).build(); + update = new TripUpdateBuilder(addedTripId, SERVICE_DATE, relationship, TIME_ZONE).build(); assertSuccess(env.applyTripUpdate(update, DIFFERENTIAL)); var snapshot = env.getTimetableSnapshot(); // Get the trip pattern of the added trip which goes through stopA - var patternsAtA = snapshot.getPatternsForStop(env.stopA1); + var patternsAtA = snapshot.getPatternsForStop(STOP_A1); assertNotNull(patternsAtA, "Added trip pattern should be found"); var tripPattern = patternsAtA.stream().findFirst().get(); diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java index d1058151dcf..ec9ba3999d3 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java @@ -6,19 +6,19 @@ import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertSuccess; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.SERVICE_DATE; import org.junit.jupiter.api.Test; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.RealTimeState; import org.opentripplanner.transit.model.timetable.TripTimes; +import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; import org.opentripplanner.updater.trip.TripUpdateBuilder; /** * Delays should be applied to the first trip but should leave the second trip untouched. */ -class DelayedTest { +class DelayedTest implements RealtimeTestConstants { private static final int DELAY = 1; private static final int STOP_SEQUENCE = 1; @@ -31,7 +31,7 @@ void singleStopDelay() { RealtimeTestEnvironment.TRIP_1_ID, RealtimeTestEnvironment.SERVICE_DATE, SCHEDULED, - env.timeZone + TIME_ZONE ) .addDelayedStopTime(STOP_SEQUENCE, DELAY) .build(); @@ -76,7 +76,7 @@ void complexDelay() { var tripId = RealtimeTestEnvironment.TRIP_2_ID; - var tripUpdate = new TripUpdateBuilder(tripId, SERVICE_DATE, SCHEDULED, env.timeZone) + var tripUpdate = new TripUpdateBuilder(tripId, SERVICE_DATE, SCHEDULED, TIME_ZONE) .addDelayedStopTime(0, 0) .addDelayedStopTime(1, 60, 80) .addDelayedStopTime(2, 90, 90) diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java index f47463a46dc..74bbcd0cc96 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java @@ -27,7 +27,7 @@ public class SkippedTest { void scheduledTripWithSkippedAndScheduled() { var env = RealtimeTestEnvironment.gtfs().withTrip2().build(); - var tripUpdate = new TripUpdateBuilder(TRIP_2_ID, SERVICE_DATE, SCHEDULED, env.timeZone) + var tripUpdate = new TripUpdateBuilder(TRIP_2_ID, SERVICE_DATE, SCHEDULED, env.TIME_ZONE) .addDelayedStopTime(0, 0) .addSkippedStop(1) .addDelayedStopTime(2, 90) @@ -59,7 +59,7 @@ void scheduledTripWithPreviouslySkipped() { var env = RealtimeTestEnvironment.gtfs().withTrip2().build(); var tripId = env.trip2().getId(); - var tripUpdate = new TripUpdateBuilder(tripId.getId(), SERVICE_DATE, SCHEDULED, env.timeZone) + var tripUpdate = new TripUpdateBuilder(tripId.getId(), SERVICE_DATE, SCHEDULED, env.TIME_ZONE) .addDelayedStopTime(0, 0) .addSkippedStop(1) .addDelayedStopTime(2, 90) @@ -72,7 +72,7 @@ void scheduledTripWithPreviouslySkipped() { tripId.getId(), SERVICE_DATE, SCHEDULED, - env.timeZone + env.TIME_ZONE ) .addDelayedStopTime(0, 0) .addDelayedStopTime(1, 50) @@ -110,7 +110,7 @@ void skippedNoData() { final FeedScopedId tripId = env.trip2().getId(); - var tripUpdate = new TripUpdateBuilder(tripId.getId(), SERVICE_DATE, SCHEDULED, env.timeZone) + var tripUpdate = new TripUpdateBuilder(tripId.getId(), SERVICE_DATE, SCHEDULED, env.TIME_ZONE) .addNoDataStop(0) .addSkippedStop(1) .addNoDataStop(2) diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java index b1bd5823592..49e2136d9f7 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java @@ -29,7 +29,7 @@ public static List cases() { void invalidTripDate(LocalDate date) { var env = RealtimeTestEnvironment.gtfs().withTrip1().build(); - var update = new TripUpdateBuilder(TRIP_1_ID, date, SCHEDULED, env.timeZone) + var update = new TripUpdateBuilder(TRIP_1_ID, date, SCHEDULED, env.TIME_ZONE) .addDelayedStopTime(2, 60, 80) .build(); From 06e485f68dc47088ce1ca31aba3d34d26887d757 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 4 Sep 2024 11:35:53 +0200 Subject: [PATCH 04/47] Use constants from interface everywhere --- .../siri/SiriTimetableSnapshotSourceTest.java | 6 ++---- .../updater/trip/RealtimeTestEnvironment.java | 4 ++-- .../trip/moduletests/delay/DelayedTest.java | 13 ++++--------- .../trip/moduletests/delay/SkippedTest.java | 18 ++++++------------ .../rejection/InvalidInputTest.java | 7 +++---- 5 files changed, 17 insertions(+), 31 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java index d77e561f0e7..28706c17142 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java @@ -160,9 +160,7 @@ void testUpdateJourneyWithFramedVehicleJourneyRef() { var updates = updatedJourneyBuilder(env) .withFramedVehicleJourneyRef(builder -> - builder - .withServiceDate(RealtimeTestEnvironment.SERVICE_DATE) - .withVehicleJourneyRef(TRIP_1_ID) + builder.withServiceDate(SERVICE_DATE).withVehicleJourneyRef(TRIP_1_ID) ) .buildEstimatedTimetableDeliveries(); var result = env.applyEstimatedTimetable(updates); @@ -206,7 +204,7 @@ void testUpdateJourneyWithFuzzyMatchingAndMissingAimedDepartureTime() { var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withFramedVehicleJourneyRef(builder -> - builder.withServiceDate(RealtimeTestEnvironment.SERVICE_DATE).withVehicleJourneyRef("XXX") + builder.withServiceDate(SERVICE_DATE).withVehicleJourneyRef("XXX") ) .withEstimatedCalls(builder -> builder diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java index 62eed418553..583cfc2c528 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java @@ -111,7 +111,7 @@ public static RealtimeTestEnvironmentBuilder gtfs() { gtfsSource = new TimetableSnapshotSource(PARAMETERS, transitModel); siriSource = null; } - dateTimeHelper = new DateTimeHelper(TIME_ZONE, RealtimeTestEnvironment.SERVICE_DATE); + dateTimeHelper = new DateTimeHelper(TIME_ZONE, SERVICE_DATE); } private RealtimeTestEnvironment withTrip1() { @@ -193,7 +193,7 @@ private EstimatedTimetableHandler getEstimatedTimetableHandler(boolean fuzzyMatc } public TripPattern getPatternForTrip(FeedScopedId tripId) { - return getPatternForTrip(tripId, RealtimeTestEnvironment.SERVICE_DATE); + return getPatternForTrip(tripId, SERVICE_DATE); } public TripPattern getPatternForTrip(FeedScopedId tripId, LocalDate serviceDate) { diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java index ec9ba3999d3..353c8bd8dcf 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java @@ -27,12 +27,7 @@ class DelayedTest implements RealtimeTestConstants { void singleStopDelay() { var env = RealtimeTestEnvironment.gtfs().withTrip1().build(); - var tripUpdate = new TripUpdateBuilder( - RealtimeTestEnvironment.TRIP_1_ID, - RealtimeTestEnvironment.SERVICE_DATE, - SCHEDULED, - TIME_ZONE - ) + var tripUpdate = new TripUpdateBuilder(TRIP_1_ID, SERVICE_DATE, SCHEDULED, TIME_ZONE) .addDelayedStopTime(STOP_SEQUENCE, DELAY) .build(); @@ -44,7 +39,7 @@ void singleStopDelay() { int trip1Index = pattern1.getScheduledTimetable().getTripIndex(env.trip1().getId()); var snapshot = env.getTimetableSnapshot(); - var trip1Realtime = snapshot.resolve(pattern1, RealtimeTestEnvironment.SERVICE_DATE); + var trip1Realtime = snapshot.resolve(pattern1, SERVICE_DATE); var trip1Scheduled = snapshot.resolve(pattern1, null); assertNotSame(trip1Realtime, trip1Scheduled); @@ -63,7 +58,7 @@ void singleStopDelay() { ); assertEquals( "UPDATED | A1 [ND] 0:00:10 0:00:11 | B1 0:00:21 0:00:22", - env.getRealtimeTimetable(RealtimeTestEnvironment.TRIP_1_ID) + env.getRealtimeTimetable(TRIP_1_ID) ); } @@ -74,7 +69,7 @@ void singleStopDelay() { void complexDelay() { var env = RealtimeTestEnvironment.gtfs().withTrip2().build(); - var tripId = RealtimeTestEnvironment.TRIP_2_ID; + var tripId = TRIP_2_ID; var tripUpdate = new TripUpdateBuilder(tripId, SERVICE_DATE, SCHEDULED, TIME_ZONE) .addDelayedStopTime(0, 0) diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java index 74bbcd0cc96..8891e753184 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java @@ -7,27 +7,26 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertSuccess; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.SERVICE_DATE; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.TRIP_2_ID; import static org.opentripplanner.updater.trip.UpdateIncrementality.DIFFERENTIAL; import org.junit.jupiter.api.Test; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.timetable.RealTimeState; import org.opentripplanner.transit.model.timetable.TripTimesStringBuilder; +import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; import org.opentripplanner.updater.trip.TripUpdateBuilder; /** * A mixture of delayed and skipped stops should result in both delayed and cancelled stops. */ -public class SkippedTest { +public class SkippedTest implements RealtimeTestConstants { @Test void scheduledTripWithSkippedAndScheduled() { var env = RealtimeTestEnvironment.gtfs().withTrip2().build(); - var tripUpdate = new TripUpdateBuilder(TRIP_2_ID, SERVICE_DATE, SCHEDULED, env.TIME_ZONE) + var tripUpdate = new TripUpdateBuilder(TRIP_2_ID, SERVICE_DATE, SCHEDULED, TIME_ZONE) .addDelayedStopTime(0, 0) .addSkippedStop(1) .addDelayedStopTime(2, 90) @@ -59,7 +58,7 @@ void scheduledTripWithPreviouslySkipped() { var env = RealtimeTestEnvironment.gtfs().withTrip2().build(); var tripId = env.trip2().getId(); - var tripUpdate = new TripUpdateBuilder(tripId.getId(), SERVICE_DATE, SCHEDULED, env.TIME_ZONE) + var tripUpdate = new TripUpdateBuilder(tripId.getId(), SERVICE_DATE, SCHEDULED, TIME_ZONE) .addDelayedStopTime(0, 0) .addSkippedStop(1) .addDelayedStopTime(2, 90) @@ -68,12 +67,7 @@ void scheduledTripWithPreviouslySkipped() { assertSuccess(env.applyTripUpdate(tripUpdate, DIFFERENTIAL)); // Create update to the same trip but now the skipped stop is no longer skipped - var scheduledBuilder = new TripUpdateBuilder( - tripId.getId(), - SERVICE_DATE, - SCHEDULED, - env.TIME_ZONE - ) + var scheduledBuilder = new TripUpdateBuilder(tripId.getId(), SERVICE_DATE, SCHEDULED, TIME_ZONE) .addDelayedStopTime(0, 0) .addDelayedStopTime(1, 50) .addDelayedStopTime(2, 90); @@ -110,7 +104,7 @@ void skippedNoData() { final FeedScopedId tripId = env.trip2().getId(); - var tripUpdate = new TripUpdateBuilder(tripId.getId(), SERVICE_DATE, SCHEDULED, env.TIME_ZONE) + var tripUpdate = new TripUpdateBuilder(tripId.getId(), SERVICE_DATE, SCHEDULED, TIME_ZONE) .addNoDataStop(0) .addSkippedStop(1) .addNoDataStop(2) diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java index 49e2136d9f7..2e04c16aba1 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java @@ -4,13 +4,12 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.updater.spi.UpdateError.UpdateErrorType.NO_SERVICE_ON_DATE; import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertFailure; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.SERVICE_DATE; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.TRIP_1_ID; import java.time.LocalDate; import java.util.List; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; +import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; import org.opentripplanner.updater.trip.TripUpdateBuilder; @@ -18,7 +17,7 @@ * A trip with start date that is outside the service period shouldn't throw an exception and is * ignored instead. */ -class InvalidInputTest { +class InvalidInputTest implements RealtimeTestConstants { public static List cases() { return List.of(SERVICE_DATE.minusYears(10), SERVICE_DATE.plusYears(10)); @@ -29,7 +28,7 @@ public static List cases() { void invalidTripDate(LocalDate date) { var env = RealtimeTestEnvironment.gtfs().withTrip1().build(); - var update = new TripUpdateBuilder(TRIP_1_ID, date, SCHEDULED, env.TIME_ZONE) + var update = new TripUpdateBuilder(TRIP_1_ID, date, SCHEDULED, TIME_ZONE) .addDelayedStopTime(2, 60, 80) .build(); From 9daec64f61710dd416f99fb9d5331d59c7a28afd Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 4 Sep 2024 11:38:03 +0200 Subject: [PATCH 05/47] Use upper case for all constants --- .../updater/trip/RealtimeTestConstants.java | 24 +++++++++---------- .../updater/trip/RealtimeTestEnvironment.java | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestConstants.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestConstants.java index cc9252bda6d..81e3759585b 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestConstants.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestConstants.java @@ -20,18 +20,18 @@ public interface RealtimeTestConstants { String OPERATOR_1_ID = "TestOperator1"; String ROUTE_1_ID = "TestRoute1"; - TransitModelForTest testModel = TransitModelForTest.of(); + TransitModelForTest TEST_MODEL = TransitModelForTest.of(); ZoneId TIME_ZONE = ZoneId.of(TransitModelForTest.TIME_ZONE_ID); - Station STATION_A = testModel.station("A").build(); - Station stationB = testModel.station("B").build(); - Station stationC = testModel.station("C").build(); - Station stationD = testModel.station("D").build(); - RegularStop STOP_A1 = testModel.stop(STOP_A1_ID).withParentStation(STATION_A).build(); - RegularStop STOP_B1 = testModel.stop(STOP_B1_ID).withParentStation(stationB).build(); - RegularStop STOP_B2 = testModel.stop("B2").withParentStation(stationB).build(); - RegularStop STOP_C1 = testModel.stop(STOP_C1_ID).withParentStation(stationC).build(); - RegularStop STOP_D1 = testModel.stop("D1").withParentStation(stationD).build(); - StopModel STOP_MODEL = testModel + Station STATION_A = TEST_MODEL.station("A").build(); + Station STATION_B = TEST_MODEL.station("B").build(); + Station STATION_C = TEST_MODEL.station("C").build(); + Station STATION_D = TEST_MODEL.station("D").build(); + RegularStop STOP_A1 = TEST_MODEL.stop(STOP_A1_ID).withParentStation(STATION_A).build(); + RegularStop STOP_B1 = TEST_MODEL.stop(STOP_B1_ID).withParentStation(STATION_B).build(); + RegularStop STOP_B2 = TEST_MODEL.stop("B2").withParentStation(STATION_B).build(); + RegularStop STOP_C1 = TEST_MODEL.stop(STOP_C1_ID).withParentStation(STATION_C).build(); + RegularStop STOP_D1 = TEST_MODEL.stop("D1").withParentStation(STATION_D).build(); + StopModel STOP_MODEL = TEST_MODEL .stopModelBuilder() .withRegularStop(STOP_A1) .withRegularStop(STOP_B1) @@ -40,5 +40,5 @@ public interface RealtimeTestConstants { .withRegularStop(STOP_D1) .build(); - Route route1 = TransitModelForTest.route(ROUTE_1_ID).build(); + Route ROUTE_1 = TransitModelForTest.route(ROUTE_1_ID).build(); } diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java index 583cfc2c528..55ba4a86b9c 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java @@ -118,7 +118,7 @@ private RealtimeTestEnvironment withTrip1() { trip1 = createTrip( TRIP_1_ID, - route1, + ROUTE_1, List.of(new StopCall(STOP_A1, 10, 11), new StopCall(STOP_B1, 20, 21)) ); transitModel.index(); @@ -129,7 +129,7 @@ private RealtimeTestEnvironment withTrip2() { trip2 = createTrip( TRIP_2_ID, - route1, + ROUTE_1, List.of( new StopCall(STOP_A1, 60, 61), new StopCall(STOP_B1, 70, 71), From 523ac2be9dbc2b64d3d21f198836b2a1ab616a90 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 4 Sep 2024 11:44:24 +0200 Subject: [PATCH 06/47] Remove static variable lookups from instances --- .../siri/SiriTimetableSnapshotSourceTest.java | 19 +++++++++---------- .../updater/trip/RealtimeTestEnvironment.java | 3 +-- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java index 28706c17142..65bf4a3c671 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java @@ -113,8 +113,7 @@ void testReplaceJourney() { .withOperatorRef(OPERATOR_1_ID) .withLineRef(ROUTE_1_ID) .withRecordedCalls(builder -> builder.call(STOP_A1).departAimedActual("00:01", "00:02")) - .withEstimatedCalls(builder -> builder.call(env.STOP_C1).arriveAimedExpected("00:03", "00:04") - ) + .withEstimatedCalls(builder -> builder.call(STOP_C1).arriveAimedExpected("00:03", "00:04")) .buildEstimatedTimetableDeliveries(); var result = env.applyEstimatedTimetable(updates); @@ -210,7 +209,7 @@ void testUpdateJourneyWithFuzzyMatchingAndMissingAimedDepartureTime() { builder .call(STOP_A1) .departAimedExpected(null, "00:00:12") - .call(env.STOP_B1) + .call(STOP_B1) .arriveAimedExpected("00:00:20", "00:00:22") ) .buildEstimatedTimetableDeliveries(); @@ -231,7 +230,7 @@ void testChangeQuay() { .withDatedVehicleJourneyRef(TRIP_1_ID) .withRecordedCalls(builder -> builder.call(STOP_A1).departAimedActual("00:00:11", "00:00:15")) .withEstimatedCalls(builder -> - builder.call(env.STOP_B2).arriveAimedExpected("00:00:20", "00:00:33") + builder.call(STOP_B2).arriveAimedExpected("00:00:20", "00:00:33") ) .buildEstimatedTimetableDeliveries(); @@ -254,9 +253,9 @@ void testCancelStop() { builder .call(STOP_A1) .departAimedExpected("00:01:01", "00:01:01") - .call(env.STOP_B1) + .call(STOP_B1) .withIsCancellation(true) - .call(env.STOP_C1) + .call(STOP_C1) .arriveAimedExpected("00:01:30", "00:01:30") ) .buildEstimatedTimetableDeliveries(); @@ -281,11 +280,11 @@ void testAddStop() { .withRecordedCalls(builder -> builder.call(STOP_A1).departAimedActual("00:00:11", "00:00:15")) .withEstimatedCalls(builder -> builder - .call(env.STOP_D1) + .call(STOP_D1) .withIsExtraCall(true) .arriveAimedExpected("00:00:19", "00:00:20") .departAimedExpected("00:00:24", "00:00:25") - .call(env.STOP_B1) + .call(STOP_B1) .arriveAimedExpected("00:00:20", "00:00:33") ) .buildEstimatedTimetableDeliveries(); @@ -330,7 +329,7 @@ void testReplaceJourneyWithoutEstimatedVehicleJourneyCode() { builder .call(STOP_A1) .departAimedExpected("00:01", "00:02") - .call(env.STOP_C1) + .call(STOP_C1) .arriveAimedExpected("00:03", "00:04") ) .buildEstimatedTimetableDeliveries(); @@ -351,7 +350,7 @@ void testNegativeHopTime() { builder .call(STOP_A1) .departAimedActual("00:00:11", "00:00:15") - .call(env.STOP_B1) + .call(STOP_B1) .arriveAimedActual("00:00:20", "00:00:14") ) .buildEstimatedTimetableDeliveries(); diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java index 55ba4a86b9c..00c343a98ab 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java @@ -8,7 +8,6 @@ import java.time.LocalDate; import java.util.List; import java.util.Objects; -import java.util.stream.Collectors; import java.util.stream.IntStream; import org.opentripplanner.DateTimeHelper; import org.opentripplanner.ext.siri.SiriFuzzyTripMatcher; @@ -343,7 +342,7 @@ private Trip createTrip(String id, Route route, List stops) { var stop = stops.get(i); return createStopTime(trip, i, stop.stop(), stop.arrivalTime(), stop.departureTime()); }) - .collect(Collectors.toList()); + .toList(); TripTimes tripTimes = TripTimesFactory.tripTimes(trip, stopTimes, null); From b06a3e326fbe20579d7318eff111880f867606e1 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 4 Sep 2024 12:26:17 +0200 Subject: [PATCH 07/47] Completely switch to constants --- .../siri/SiriTimetableSnapshotSourceTest.java | 16 +- .../updater/trip/RealtimeTestEnvironment.java | 139 +----------------- .../trip/RealtimeTestEnvironmentBuilder.java | 111 +++++++++++++- .../CancellationDeletionTest.java | 5 +- .../trip/moduletests/delay/DelayedTest.java | 18 +-- .../trip/moduletests/delay/SkippedTest.java | 15 +- 6 files changed, 141 insertions(+), 163 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java index 65bf4a3c671..8272d0c43af 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java @@ -16,7 +16,7 @@ class SiriTimetableSnapshotSourceTest implements RealtimeTestConstants { void testCancelTrip() { var env = RealtimeTestEnvironment.siri().withTrip1().build(); - assertEquals(RealTimeState.SCHEDULED, env.getTripTimesForTrip(env.trip1()).getRealTimeState()); + assertEquals(RealTimeState.SCHEDULED, env.getTripTimesForTrip(TRIP_1_ID).getRealTimeState()); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withDatedVehicleJourneyRef(TRIP_1_ID) @@ -26,7 +26,7 @@ void testCancelTrip() { var result = env.applyEstimatedTimetable(updates); assertEquals(1, result.successful()); - assertEquals(RealTimeState.CANCELED, env.getTripTimesForTrip(env.trip1()).getRealTimeState()); + assertEquals(RealTimeState.CANCELED, env.getTripTimesForTrip(TRIP_1_ID).getRealTimeState()); } @Test @@ -127,7 +127,7 @@ void testReplaceJourney() { ); // Original trip should not get canceled - var originalTripTimes = env.getTripTimesForTrip(env.trip1()); + var originalTripTimes = env.getTripTimesForTrip(TRIP_1_ID); assertEquals(RealTimeState.SCHEDULED, originalTripTimes.getRealTimeState()); } @@ -146,7 +146,7 @@ void testUpdateJourneyWithDatedVehicleJourneyRef() { assertTripUpdated(env); assertEquals( "UPDATED | A1 0:00:15 0:00:15 | B1 0:00:25 0:00:25", - env.getRealtimeTimetable(env.trip1()) + env.getRealtimeTimetable(TRIP_1_ID) ); } @@ -239,7 +239,7 @@ void testChangeQuay() { assertEquals(1, result.successful()); assertEquals( "MODIFIED | A1 [R] 0:00:15 0:00:15 | B2 0:00:33 0:00:33", - env.getRealtimeTimetable(env.trip1()) + env.getRealtimeTimetable(TRIP_1_ID) ); } @@ -265,7 +265,7 @@ void testCancelStop() { assertEquals(1, result.successful()); assertEquals( "MODIFIED | A1 0:01:01 0:01:01 | B1 [C] 0:01:10 0:01:11 | C1 0:01:30 0:01:30", - env.getRealtimeTimetable(env.trip2()) + env.getRealtimeTimetable(TRIP_2_ID) ); } @@ -294,7 +294,7 @@ void testAddStop() { assertEquals(1, result.successful()); assertEquals( "MODIFIED | A1 0:00:15 0:00:15 | D1 [C] 0:00:20 0:00:25 | B1 0:00:33 0:00:33", - env.getRealtimeTimetable(env.trip1()) + env.getRealtimeTimetable(TRIP_1_ID) ); } @@ -423,7 +423,7 @@ private static SiriEtBuilder updatedJourneyBuilder(RealtimeTestEnvironment env) private static void assertTripUpdated(RealtimeTestEnvironment env) { assertEquals( "UPDATED | A1 0:00:15 0:00:15 | B1 0:00:25 0:00:25", - env.getRealtimeTimetable(env.trip1()) + env.getRealtimeTimetable(TRIP_1_ID) ); } } diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java index 00c343a98ab..431ffbe0b56 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java @@ -8,27 +8,16 @@ import java.time.LocalDate; import java.util.List; import java.util.Objects; -import java.util.stream.IntStream; import org.opentripplanner.DateTimeHelper; import org.opentripplanner.ext.siri.SiriFuzzyTripMatcher; import org.opentripplanner.ext.siri.SiriTimetableSnapshotSource; import org.opentripplanner.ext.siri.updater.EstimatedTimetableHandler; -import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; -import org.opentripplanner.model.StopTime; import org.opentripplanner.model.TimetableSnapshot; -import org.opentripplanner.model.calendar.CalendarServiceData; import org.opentripplanner.transit.model._data.TransitModelForTest; -import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; -import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.TripPattern; -import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.timetable.Trip; -import org.opentripplanner.transit.model.timetable.TripOnServiceDate; import org.opentripplanner.transit.model.timetable.TripTimes; -import org.opentripplanner.transit.model.timetable.TripTimesFactory; import org.opentripplanner.transit.model.timetable.TripTimesStringBuilder; import org.opentripplanner.transit.service.DefaultTransitService; import org.opentripplanner.transit.service.TransitModel; @@ -57,9 +46,6 @@ public final class RealtimeTestEnvironment implements RealtimeTestConstants { private final TimetableSnapshotSource gtfsSource; private final DateTimeHelper dateTimeHelper; - private Trip trip1; - private Trip trip2; - enum SourceType { GTFS_RT, SIRI, @@ -79,27 +65,10 @@ public static RealtimeTestEnvironmentBuilder gtfs() { return new RealtimeTestEnvironmentBuilder().withSourceType(SourceType.GTFS_RT); } - RealtimeTestEnvironment(SourceType sourceType, boolean withTrip1, boolean withTrip2) { - transitModel = new TransitModel(STOP_MODEL, new Deduplicator()); - transitModel.initTimeZone(TIME_ZONE); - transitModel.addAgency(TransitModelForTest.AGENCY); - - CalendarServiceData calendarServiceData = new CalendarServiceData(); - calendarServiceData.putServiceDatesForServiceId( - SERVICE_ID, - List.of(SERVICE_DATE.minusDays(1), SERVICE_DATE, SERVICE_DATE.plusDays(1)) - ); - transitModel.getServiceCodes().put(SERVICE_ID, 0); - transitModel.updateCalendarServiceData(true, calendarServiceData, DataImportIssueStore.NOOP); - - if (withTrip1) { - withTrip1(); - } - if (withTrip2) { - withTrip2(); - } + RealtimeTestEnvironment(SourceType sourceType, TransitModel transitModel) { + this.transitModel = transitModel; - transitModel.index(); + this.transitModel.index(); // SIRI and GTFS-RT cannot be registered with the transit model at the same time // we are actively refactoring to remove this restriction // for the time being you cannot run a SIRI and GTFS-RT test at the same time @@ -113,49 +82,6 @@ public static RealtimeTestEnvironmentBuilder gtfs() { dateTimeHelper = new DateTimeHelper(TIME_ZONE, SERVICE_DATE); } - private RealtimeTestEnvironment withTrip1() { - trip1 = - createTrip( - TRIP_1_ID, - ROUTE_1, - List.of(new StopCall(STOP_A1, 10, 11), new StopCall(STOP_B1, 20, 21)) - ); - transitModel.index(); - return this; - } - - private RealtimeTestEnvironment withTrip2() { - trip2 = - createTrip( - TRIP_2_ID, - ROUTE_1, - List.of( - new StopCall(STOP_A1, 60, 61), - new StopCall(STOP_B1, 70, 71), - new StopCall(STOP_C1, 80, 81) - ) - ); - - transitModel.index(); - return this; - } - - public Trip trip1() { - Objects.requireNonNull( - trip1, - "trip1 was not added to the test environment. Call withTrip1() to add it." - ); - return trip1; - } - - public Trip trip2() { - Objects.requireNonNull( - trip2, - "trip2 was not added to the test environment. Call withTrip2() to add it." - ); - return trip2; - } - public static FeedScopedId id(String id) { return TransitModelForTest.id(id); } @@ -195,6 +121,10 @@ public TripPattern getPatternForTrip(FeedScopedId tripId) { return getPatternForTrip(tripId, SERVICE_DATE); } + public TripPattern getPatternForTrip(String id) { + return getPatternForTrip(id(id)); + } + public TripPattern getPatternForTrip(FeedScopedId tripId, LocalDate serviceDate) { var transitService = getTransitService(); var trip = transitService.getTripOnServiceDateById(tripId); @@ -319,59 +249,4 @@ private void commitTimetableSnapshot() { gtfsSource.flushBuffer(); } } - - private Trip createTrip(String id, Route route, List stops) { - var trip = Trip - .of(id(id)) - .withRoute(route) - .withHeadsign(I18NString.of("Headsign of %s".formatted(id))) - .withServiceId(SERVICE_ID) - .build(); - - var tripOnServiceDate = TripOnServiceDate - .of(trip.getId()) - .withTrip(trip) - .withServiceDate(SERVICE_DATE) - .build(); - - transitModel.addTripOnServiceDate(tripOnServiceDate.getId(), tripOnServiceDate); - - var stopTimes = IntStream - .range(0, stops.size()) - .mapToObj(i -> { - var stop = stops.get(i); - return createStopTime(trip, i, stop.stop(), stop.arrivalTime(), stop.departureTime()); - }) - .toList(); - - TripTimes tripTimes = TripTimesFactory.tripTimes(trip, stopTimes, null); - - final TripPattern pattern = TransitModelForTest - .tripPattern(id + "Pattern", route) - .withStopPattern(TransitModelForTest.stopPattern(stops.stream().map(StopCall::stop).toList())) - .build(); - pattern.add(tripTimes); - - transitModel.addTripPattern(pattern.getId(), pattern); - - return trip; - } - - private StopTime createStopTime( - Trip trip, - int stopSequence, - StopLocation stop, - int arrivalTime, - int departureTime - ) { - var st = new StopTime(); - st.setTrip(trip); - st.setStopSequence(stopSequence); - st.setStop(stop); - st.setArrivalTime(arrivalTime); - st.setDepartureTime(departureTime); - return st; - } - - private record StopCall(RegularStop stop, int arrivalTime, int departureTime) {} } diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java index ff15c845742..fceaa31b8df 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java @@ -1,12 +1,30 @@ package org.opentripplanner.updater.trip; +import static org.opentripplanner.transit.model._data.TransitModelForTest.id; + +import java.util.List; import java.util.Objects; +import java.util.stream.IntStream; +import org.opentripplanner.framework.i18n.I18NString; +import org.opentripplanner.graph_builder.issue.api.DataImportIssueStore; +import org.opentripplanner.model.StopTime; +import org.opentripplanner.model.calendar.CalendarServiceData; +import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model.framework.Deduplicator; +import org.opentripplanner.transit.model.network.Route; +import org.opentripplanner.transit.model.network.TripPattern; +import org.opentripplanner.transit.model.site.RegularStop; +import org.opentripplanner.transit.model.site.StopLocation; +import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.transit.model.timetable.TripOnServiceDate; +import org.opentripplanner.transit.model.timetable.TripTimes; +import org.opentripplanner.transit.model.timetable.TripTimesFactory; +import org.opentripplanner.transit.service.TransitModel; -public class RealtimeTestEnvironmentBuilder { +public class RealtimeTestEnvironmentBuilder implements RealtimeTestConstants { private RealtimeTestEnvironment.SourceType sourceType; - private boolean withTrip1 = false; - private boolean withTrip2 = false; + private final TransitModel transitModel = new TransitModel(STOP_MODEL, new Deduplicator()); RealtimeTestEnvironmentBuilder withSourceType(RealtimeTestEnvironment.SourceType sourceType) { this.sourceType = sourceType; @@ -14,17 +32,98 @@ RealtimeTestEnvironmentBuilder withSourceType(RealtimeTestEnvironment.SourceType } public RealtimeTestEnvironmentBuilder withTrip1() { - withTrip1 = true; + createTrip( + TRIP_1_ID, + ROUTE_1, + List.of(new StopCall(STOP_A1, 10, 11), new StopCall(STOP_B1, 20, 21)) + ); + transitModel.index(); return this; } public RealtimeTestEnvironmentBuilder withTrip2() { - withTrip2 = true; + createTrip( + TRIP_2_ID, + ROUTE_1, + List.of( + new StopCall(STOP_A1, 60, 61), + new StopCall(STOP_B1, 70, 71), + new StopCall(STOP_C1, 80, 81) + ) + ); + + transitModel.index(); return this; } public RealtimeTestEnvironment build() { Objects.requireNonNull(sourceType, "sourceType cannot be null"); - return new RealtimeTestEnvironment(sourceType, withTrip1, withTrip2); + transitModel.initTimeZone(TIME_ZONE); + transitModel.addAgency(TransitModelForTest.AGENCY); + + CalendarServiceData calendarServiceData = new CalendarServiceData(); + calendarServiceData.putServiceDatesForServiceId( + SERVICE_ID, + List.of(SERVICE_DATE.minusDays(1), SERVICE_DATE, SERVICE_DATE.plusDays(1)) + ); + transitModel.getServiceCodes().put(SERVICE_ID, 0); + transitModel.updateCalendarServiceData(true, calendarServiceData, DataImportIssueStore.NOOP); + + return new RealtimeTestEnvironment(sourceType, transitModel); + } + + private Trip createTrip(String id, Route route, List stops) { + var trip = Trip + .of(id(id)) + .withRoute(route) + .withHeadsign(I18NString.of("Headsign of %s".formatted(id))) + .withServiceId(SERVICE_ID) + .build(); + + var tripOnServiceDate = TripOnServiceDate + .of(trip.getId()) + .withTrip(trip) + .withServiceDate(SERVICE_DATE) + .build(); + + transitModel.addTripOnServiceDate(tripOnServiceDate.getId(), tripOnServiceDate); + + var stopTimes = IntStream + .range(0, stops.size()) + .mapToObj(i -> { + var stop = stops.get(i); + return createStopTime(trip, i, stop.stop(), stop.arrivalTime(), stop.departureTime()); + }) + .toList(); + + TripTimes tripTimes = TripTimesFactory.tripTimes(trip, stopTimes, null); + + final TripPattern pattern = TransitModelForTest + .tripPattern(id + "Pattern", route) + .withStopPattern(TransitModelForTest.stopPattern(stops.stream().map(StopCall::stop).toList())) + .build(); + pattern.add(tripTimes); + + transitModel.addTripPattern(pattern.getId(), pattern); + + return trip; + } + + private static StopTime createStopTime( + Trip trip, + int stopSequence, + StopLocation stop, + int arrivalTime, + int departureTime + ) { + var st = new StopTime(); + st.setTrip(trip); + st.setStopSequence(stopSequence); + st.setStop(stop); + st.setArrivalTime(arrivalTime); + st.setDepartureTime(departureTime); + return st; } + + private record StopCall(RegularStop stop, int arrivalTime, int departureTime) {} } diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java index eb304189e47..f619aceef78 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java @@ -4,6 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.transit.model._data.TransitModelForTest.id; import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertSuccess; import static org.opentripplanner.updater.trip.UpdateIncrementality.DIFFERENTIAL; @@ -34,9 +35,9 @@ static List cases() { @MethodSource("cases") void cancelledTrip(ScheduleRelationship relationship, RealTimeState state) { var env = RealtimeTestEnvironment.gtfs().withTrip1().build(); - var pattern1 = env.getPatternForTrip(env.trip1()); + var pattern1 = env.getPatternForTrip(TRIP_1_ID); - final int tripIndex1 = pattern1.getScheduledTimetable().getTripIndex(env.trip1().getId()); + final int tripIndex1 = pattern1.getScheduledTimetable().getTripIndex(id(TRIP_1_ID)); var update = new TripUpdateBuilder(TRIP_1_ID, SERVICE_DATE, relationship, TIME_ZONE).build(); assertSuccess(env.applyTripUpdate(update)); diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java index 353c8bd8dcf..5b2f5326599 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java @@ -5,12 +5,11 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.transit.model._data.TransitModelForTest.id; import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertSuccess; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.RealTimeState; -import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; import org.opentripplanner.updater.trip.TripUpdateBuilder; @@ -35,8 +34,8 @@ void singleStopDelay() { assertEquals(1, result.successful()); - var pattern1 = env.getPatternForTrip(env.trip1()); - int trip1Index = pattern1.getScheduledTimetable().getTripIndex(env.trip1().getId()); + var pattern1 = env.getPatternForTrip(TRIP_1_ID); + int trip1Index = pattern1.getScheduledTimetable().getTripIndex(id(TRIP_1_ID)); var snapshot = env.getTimetableSnapshot(); var trip1Realtime = snapshot.resolve(pattern1, SERVICE_DATE); @@ -54,7 +53,7 @@ void singleStopDelay() { assertEquals( "SCHEDULED | A1 0:00:10 0:00:11 | B1 0:00:20 0:00:21", - env.getScheduledTimetable(env.trip1().getId()) + env.getScheduledTimetable(id(TRIP_1_ID)) ); assertEquals( "UPDATED | A1 [ND] 0:00:10 0:00:11 | B1 0:00:21 0:00:22", @@ -81,7 +80,8 @@ void complexDelay() { var snapshot = env.getTimetableSnapshot(); - final TripPattern originalTripPattern = env.getTransitService().getPatternForTrip(env.trip2()); + var trip2 = env.getTransitService().getTripForId(id(tripId)); + var originalTripPattern = env.getTransitService().getPatternForTrip(trip2); var originalTimetableForToday = snapshot.resolve(originalTripPattern, SERVICE_DATE); var originalTimetableScheduled = snapshot.resolve(originalTripPattern, null); @@ -93,7 +93,7 @@ void complexDelay() { originalTripIndexScheduled > -1, "Original trip should be found in scheduled time table" ); - final TripTimes originalTripTimesScheduled = originalTimetableScheduled.getTripTimes( + var originalTripTimesScheduled = originalTimetableScheduled.getTripTimes( originalTripIndexScheduled ); assertFalse( @@ -110,11 +110,11 @@ void complexDelay() { assertEquals( "SCHEDULED | A1 0:01 0:01:01 | B1 0:01:10 0:01:11 | C1 0:01:20 0:01:21", - env.getScheduledTimetable(env.trip2().getId()) + env.getScheduledTimetable(TRIP_2_ID) ); assertEquals( "UPDATED | A1 0:01 0:01:01 | B1 0:02:10 0:02:31 | C1 0:02:50 0:02:51", - env.getRealtimeTimetable(env.trip2()) + env.getRealtimeTimetable(TRIP_2_ID) ); } } diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java index 8891e753184..b9936a2bfc5 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java @@ -6,6 +6,7 @@ import static org.junit.jupiter.api.Assertions.assertNotSame; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.opentripplanner.transit.model._data.TransitModelForTest.id; import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertSuccess; import static org.opentripplanner.updater.trip.UpdateIncrementality.DIFFERENTIAL; @@ -34,9 +35,10 @@ void scheduledTripWithSkippedAndScheduled() { assertSuccess(env.applyTripUpdate(tripUpdate)); - assertOriginalTripPatternIsDeleted(env, env.trip2().getId()); + var trip2Id = id(TRIP_2_ID); + assertOriginalTripPatternIsDeleted(env, trip2Id); - assertNewTripTimesIsUpdated(env, env.trip2().getId()); + assertNewTripTimesIsUpdated(env, trip2Id); assertEquals( "UPDATED | A1 0:01 0:01:01 | B1 [C] 0:01:52 0:01:58 | C1 0:02:50 0:02:51", @@ -56,7 +58,7 @@ void scheduledTripWithSkippedAndScheduled() { @Test void scheduledTripWithPreviouslySkipped() { var env = RealtimeTestEnvironment.gtfs().withTrip2().build(); - var tripId = env.trip2().getId(); + var tripId = id(TRIP_2_ID); var tripUpdate = new TripUpdateBuilder(tripId.getId(), SERVICE_DATE, SCHEDULED, TIME_ZONE) .addDelayedStopTime(0, 0) @@ -102,7 +104,7 @@ void scheduledTripWithPreviouslySkipped() { void skippedNoData() { var env = RealtimeTestEnvironment.gtfs().withTrip2().build(); - final FeedScopedId tripId = env.trip2().getId(); + final FeedScopedId tripId = id(TRIP_2_ID); var tripUpdate = new TripUpdateBuilder(tripId.getId(), SERVICE_DATE, SCHEDULED, TIME_ZONE) .addNoDataStop(0) @@ -118,7 +120,7 @@ void skippedNoData() { assertEquals( "UPDATED | A1 [ND] 0:01 0:01:01 | B1 [C] 0:01:10 0:01:11 | C1 [ND] 0:01:20 0:01:21", - env.getRealtimeTimetable(env.trip2()) + env.getRealtimeTimetable(tripId.getId()) ); } @@ -172,7 +174,8 @@ private static void assertNewTripTimesIsUpdated( RealtimeTestEnvironment env, FeedScopedId tripId ) { - var originalTripPattern = env.getTransitService().getPatternForTrip(env.trip2()); + var trip = env.getTransitService().getTripForId(tripId); + var originalTripPattern = env.getTransitService().getPatternForTrip(trip); var snapshot = env.getTimetableSnapshot(); var originalTimetableForToday = snapshot.resolve(originalTripPattern, SERVICE_DATE); From 2e74f275de4c72b56e5d80fefc232ab5c6b34f7b Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 4 Sep 2024 12:55:49 +0200 Subject: [PATCH 08/47] Clean up --- .../updater/trip/RealtimeTestEnvironment.java | 22 ++----------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java index 431ffbe0b56..df5a54db7bc 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java @@ -1,5 +1,6 @@ package org.opentripplanner.updater.trip; +import static org.opentripplanner.transit.model._data.TransitModelForTest.id; import static org.opentripplanner.updater.trip.UpdateIncrementality.DIFFERENTIAL; import static org.opentripplanner.updater.trip.UpdateIncrementality.FULL_DATASET; @@ -16,7 +17,6 @@ import org.opentripplanner.transit.model._data.TransitModelForTest; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.TripPattern; -import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.model.timetable.TripTimesStringBuilder; import org.opentripplanner.transit.service.DefaultTransitService; @@ -66,6 +66,7 @@ public static RealtimeTestEnvironmentBuilder gtfs() { } RealtimeTestEnvironment(SourceType sourceType, TransitModel transitModel) { + Objects.requireNonNull(sourceType); this.transitModel = transitModel; this.transitModel.index(); @@ -82,10 +83,6 @@ public static RealtimeTestEnvironmentBuilder gtfs() { dateTimeHelper = new DateTimeHelper(TIME_ZONE, SERVICE_DATE); } - public static FeedScopedId id(String id) { - return TransitModelForTest.id(id); - } - /** * Returns a new fresh TransitService */ @@ -131,13 +128,6 @@ public TripPattern getPatternForTrip(FeedScopedId tripId, LocalDate serviceDate) return transitService.getPatternForTrip(trip.getTrip(), serviceDate); } - /** - * Find the current TripTimes for a trip id on the default serviceDate - */ - public TripTimes getTripTimesForTrip(Trip trip) { - return getTripTimesForTrip(trip.getId(), SERVICE_DATE); - } - /** * Find the current TripTimes for a trip id on the default serviceDate */ @@ -149,10 +139,6 @@ public DateTimeHelper getDateTimeHelper() { return dateTimeHelper; } - public TripPattern getPatternForTrip(Trip trip) { - return getTransitService().getPatternForTrip(trip); - } - public TimetableSnapshot getTimetableSnapshot() { if (siriSource != null) { return siriSource.getTimetableSnapshot(); @@ -165,10 +151,6 @@ public String getRealtimeTimetable(String tripId) { return getRealtimeTimetable(id(tripId), SERVICE_DATE); } - public String getRealtimeTimetable(Trip trip) { - return getRealtimeTimetable(trip.getId(), SERVICE_DATE); - } - public String getRealtimeTimetable(FeedScopedId tripId, LocalDate serviceDate) { var tt = getTripTimesForTrip(tripId, serviceDate); var pattern = getPatternForTrip(tripId); From cd50516d2b5c4d9164c283e5cd2438db2a8ed371 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 4 Sep 2024 14:31:20 +0200 Subject: [PATCH 09/47] Remove 'public' --- .../updater/trip/moduletests/delay/SkippedTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java index b9936a2bfc5..7658ac4d5ad 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java @@ -21,7 +21,7 @@ /** * A mixture of delayed and skipped stops should result in both delayed and cancelled stops. */ -public class SkippedTest implements RealtimeTestConstants { +class SkippedTest implements RealtimeTestConstants { @Test void scheduledTripWithSkippedAndScheduled() { From aba7f8088f432825423f768da62ead882d5ef3dc Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 8 Aug 2024 23:24:21 +0200 Subject: [PATCH 10/47] Filter stops by current service week --- .../ext/vectortiles/VectorTilesResource.java | 15 ++++++++- .../vectortiles/layers/stops/Predicates.java | 31 +++++++++++++++++++ .../layers/stops/StopsLayerBuilder.java | 20 ++++++------ .../gtfs/PatternByServiceDatesFilter.java | 8 +++++ .../config/routerconfig/VectorTileConfig.java | 10 +++--- 5 files changed, 67 insertions(+), 17 deletions(-) create mode 100644 src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/Predicates.java diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java index 29701ee2307..cbd5b7b082d 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java @@ -20,6 +20,7 @@ import org.opentripplanner.apis.support.TileJson; import org.opentripplanner.ext.vectortiles.layers.areastops.AreaStopsLayerBuilder; import org.opentripplanner.ext.vectortiles.layers.stations.StationsLayerBuilder; +import org.opentripplanner.ext.vectortiles.layers.stops.Predicates; import org.opentripplanner.ext.vectortiles.layers.stops.StopsLayerBuilder; import org.opentripplanner.ext.vectortiles.layers.vehicleparkings.VehicleParkingGroupsLayerBuilder; import org.opentripplanner.ext.vectortiles.layers.vehicleparkings.VehicleParkingsLayerBuilder; @@ -122,7 +123,18 @@ private static LayerBuilder createLayerBuilder( OtpServerRequestContext context ) { return switch (layerParameters.type()) { - case Stop -> new StopsLayerBuilder(context.transitService(), layerParameters, locale); + case Stop -> new StopsLayerBuilder( + context.transitService(), + layerParameters, + locale, + Predicates.NO_FILTER + ); + case CurrentServiceWeekStop -> new StopsLayerBuilder( + context.transitService(), + layerParameters, + locale, + Predicates.currentServiceWeek(context.transitService()) + ); case Station -> new StationsLayerBuilder(context.transitService(), layerParameters, locale); case AreaStop -> new AreaStopsLayerBuilder(context.transitService(), layerParameters, locale); case VehicleRental -> new VehicleRentalPlacesLayerBuilder( @@ -154,6 +166,7 @@ private static LayerBuilder createLayerBuilder( public enum LayerType { Stop, + CurrentServiceWeekStop, Station, AreaStop, VehicleRental, diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/Predicates.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/Predicates.java new file mode 100644 index 00000000000..9b38587c22d --- /dev/null +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/Predicates.java @@ -0,0 +1,31 @@ +package org.opentripplanner.ext.vectortiles.layers.stops; + +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.temporal.TemporalAdjusters; +import java.util.function.Predicate; +import org.opentripplanner.apis.gtfs.PatternByServiceDatesFilter; +import org.opentripplanner.apis.gtfs.model.LocalDateRange; +import org.opentripplanner.transit.model.site.RegularStop; +import org.opentripplanner.transit.service.TransitService; + +public class Predicates { + + public static final Predicate NO_FILTER = x -> true; + + public static Predicate currentServiceWeek(TransitService transitService) { + var serviceDate = LocalDate.now(transitService.getTimeZone()); + var lastSunday = serviceDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY)); + var nextSunday = serviceDate.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)).plusDays(1); + var filter = new PatternByServiceDatesFilter( + new LocalDateRange(lastSunday, nextSunday), + transitService + ); + + return regularStop -> { + var patterns = transitService.getPatternsForStop(regularStop); + var patternsInCurrentWeek = filter.filterPatterns(patterns); + return !patternsInCurrentWeek.isEmpty(); + }; + } +} diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java index aa664497728..a05851a90db 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java @@ -5,32 +5,28 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.function.BiFunction; -import java.util.stream.Collectors; +import java.util.function.Predicate; import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.apis.support.mapping.PropertyMapper; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.service.TransitService; -public class StopsLayerBuilder extends LayerBuilder { +public class StopsLayerBuilder extends LayerBuilder { - static Map>> mappers = Map.of( - MapperType.Digitransit, - DigitransitStopPropertyMapper::create - ); private final TransitService transitService; + private final Predicate filter; public StopsLayerBuilder( TransitService transitService, LayerParameters layerParameters, - Locale locale + Locale locale, + Predicate filter ) { super( - (PropertyMapper) Map + Map .ofEntries( entry(MapperType.Digitransit, new DigitransitStopPropertyMapper(transitService, locale)), entry( @@ -43,12 +39,14 @@ public StopsLayerBuilder( layerParameters.expansionFactor() ); this.transitService = transitService; + this.filter = filter; } protected List getGeometries(Envelope query) { return transitService .findRegularStops(query) .stream() + .filter(filter) .map(stop -> { Geometry point = stop.getGeometry(); @@ -56,7 +54,7 @@ protected List getGeometries(Envelope query) { return point; }) - .collect(Collectors.toList()); + .toList(); } enum MapperType { diff --git a/src/main/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilter.java b/src/main/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilter.java index 8eecfe6273b..fc980da4380 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilter.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilter.java @@ -56,6 +56,14 @@ public PatternByServiceDatesFilter( ); } + public PatternByServiceDatesFilter(LocalDateRange range, TransitService transitService) { + this( + range, + transitService::getPatternsForRoute, + trip -> transitService.getCalendarService().getServiceDatesForServiceId(trip.getServiceId()) + ); + } + /** * Filter the patterns by the service dates that it operates on. */ diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java index 96cd49b72bb..d924a5a8328 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java @@ -12,14 +12,14 @@ import java.util.Optional; import javax.annotation.Nullable; import org.opentripplanner.ext.vectortiles.VectorTilesResource; +import org.opentripplanner.ext.vectortiles.VectorTilesResource.LayerType; import org.opentripplanner.inspector.vector.LayerParameters; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; -public class VectorTileConfig - implements VectorTilesResource.LayersParameters { +public class VectorTileConfig implements VectorTilesResource.LayersParameters { public static final VectorTileConfig DEFAULT = new VectorTileConfig(List.of(), null, null); - private final List> layers; + private final List> layers; @Nullable private final String basePath; @@ -28,7 +28,7 @@ public class VectorTileConfig private final String attribution; VectorTileConfig( - Collection> layers, + Collection> layers, @Nullable String basePath, @Nullable String attribution ) { @@ -38,7 +38,7 @@ public class VectorTileConfig } @Override - public List> layers() { + public List> layers() { return layers; } From 526e3f208904a086f681d2708ced7df2fc53878f Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 9 Aug 2024 10:22:31 +0200 Subject: [PATCH 11/47] Update example file --- .../examples/ibi/portland/router-config.json | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/doc/user/examples/ibi/portland/router-config.json b/doc/user/examples/ibi/portland/router-config.json index 0bf3547dbfd..d89fc05ec3b 100644 --- a/doc/user/examples/ibi/portland/router-config.json +++ b/doc/user/examples/ibi/portland/router-config.json @@ -59,6 +59,61 @@ "url": "https://gbfs.spin.pm/api/gbfs/v2/portland" } ], + "vectorTiles": { + "basePath": "/rtp/routers/default/vectorTiles", + "attribution": "Regional Partners", + "layers": [ + { + "name": "stops", + "type": "CurrentServiceWeekStop", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 14, + "cacheMaxSeconds": 600 + }, + { + "name": "areaStops", + "type": "AreaStop", + "mapper": "OTPRR", + "maxZoom": 30, + "minZoom": 8, + "cacheMaxSeconds": 600 + }, + { + "name": "stations", + "type": "Station", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 2, + "cacheMaxSeconds": 600 + }, + { + "name": "rentalVehicles", + "type": "VehicleRentalVehicle", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 2, + "cacheMaxSeconds": 60 + }, + { + "name": "rentalStations", + "type": "VehicleRentalStation", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 2, + "cacheMaxSeconds": 600 + }, + { + "name": "vehicleParking", + "type": "VehicleParking", + "mapper": "Digitransit", + "maxZoom": 20, + "minZoom": 10, + "cacheMaxSeconds": 60, + "expansionFactor": 0.25 + } + ] + }, "rideHailingServices": [ { "type": "uber-car-hailing", From 6f1db53bee037b92f91703d93322d6dbf2c04551 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 4 Sep 2024 18:13:28 +0200 Subject: [PATCH 12/47] Introduce vector tile filters --- .../examples/ibi/portland/router-config.json | 5 +++-- doc/user/sandbox/MapboxVectorTilesApi.md | 13 +++++++++++++ .../ext/vectortiles/VectorTilesResource.java | 15 +-------------- .../{Predicates.java => StopPredicates.java} | 14 +++++++++++++- .../layers/stops/StopsLayerBuilder.java | 5 ++--- .../inspector/vector/LayerParameters.java | 5 +++++ .../config/routerconfig/VectorTileConfig.java | 18 ++++++++++++++++-- 7 files changed, 53 insertions(+), 22 deletions(-) rename src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/{Predicates.java => StopPredicates.java} (77%) diff --git a/doc/user/examples/ibi/portland/router-config.json b/doc/user/examples/ibi/portland/router-config.json index d89fc05ec3b..33810d7054e 100644 --- a/doc/user/examples/ibi/portland/router-config.json +++ b/doc/user/examples/ibi/portland/router-config.json @@ -65,11 +65,12 @@ "layers": [ { "name": "stops", - "type": "CurrentServiceWeekStop", + "type": "Stop", "mapper": "Digitransit", "maxZoom": 20, "minZoom": 14, - "cacheMaxSeconds": 600 + "cacheMaxSeconds": 600, + "filter": "CURRENT_TRIMET_SERVICE_WEEK" }, { "name": "areaStops", diff --git a/doc/user/sandbox/MapboxVectorTilesApi.md b/doc/user/sandbox/MapboxVectorTilesApi.md index 62f3bd36c38..9720f4e95f9 100644 --- a/doc/user/sandbox/MapboxVectorTilesApi.md +++ b/doc/user/sandbox/MapboxVectorTilesApi.md @@ -173,6 +173,7 @@ For each layer, the configuration includes: |       type = "stop" | `enum` | Type of the layer. | *Required* | | 2.0 | |       [cacheMaxSeconds](#vectorTiles_layers_0_cacheMaxSeconds) | `integer` | Sets the cache header in the response. | *Optional* | `-1` | 2.0 | |       [expansionFactor](#vectorTiles_layers_0_expansionFactor) | `double` | How far outside its boundaries should the tile contain information. | *Optional* | `0.25` | 2.0 | +|       [filter](#vectorTiles_layers_0_filter) | `enum` | Reduce the result set of a layer further by a specific filter. | *Optional* | `"none"` | 2.6 | |       [mapper](#vectorTiles_layers_0_mapper) | `string` | Describes the mapper converting from the OTP model entities to the vector tile properties. | *Required* | | 2.0 | |       maxZoom | `integer` | Maximum zoom levels the layer is active for. | *Optional* | `20` | 2.0 | |       minZoom | `integer` | Minimum zoom levels the layer is active for. | *Optional* | `9` | 2.0 | @@ -245,6 +246,18 @@ How far outside its boundaries should the tile contain information. The value is a fraction of the tile size. If you are having problem with icons and shapes being clipped at tile edges, then increase this number. +

filter

+ +**Since version:** `2.6` ∙ **Type:** `enum` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"none"` +**Path:** /vectorTiles/layers/[0] +**Enum values:** `none` | `current-trimet-service-week` + +Reduce the result set of a layer further by a specific filter. + +This is useful for when the schema of a layer, say stops, should remain unchanged but some +elements should not be included in the result. + +

mapper

**Since version:** `2.0` ∙ **Type:** `string` ∙ **Cardinality:** `Required` diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java index cbd5b7b082d..29701ee2307 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/VectorTilesResource.java @@ -20,7 +20,6 @@ import org.opentripplanner.apis.support.TileJson; import org.opentripplanner.ext.vectortiles.layers.areastops.AreaStopsLayerBuilder; import org.opentripplanner.ext.vectortiles.layers.stations.StationsLayerBuilder; -import org.opentripplanner.ext.vectortiles.layers.stops.Predicates; import org.opentripplanner.ext.vectortiles.layers.stops.StopsLayerBuilder; import org.opentripplanner.ext.vectortiles.layers.vehicleparkings.VehicleParkingGroupsLayerBuilder; import org.opentripplanner.ext.vectortiles.layers.vehicleparkings.VehicleParkingsLayerBuilder; @@ -123,18 +122,7 @@ private static LayerBuilder createLayerBuilder( OtpServerRequestContext context ) { return switch (layerParameters.type()) { - case Stop -> new StopsLayerBuilder( - context.transitService(), - layerParameters, - locale, - Predicates.NO_FILTER - ); - case CurrentServiceWeekStop -> new StopsLayerBuilder( - context.transitService(), - layerParameters, - locale, - Predicates.currentServiceWeek(context.transitService()) - ); + case Stop -> new StopsLayerBuilder(context.transitService(), layerParameters, locale); case Station -> new StationsLayerBuilder(context.transitService(), layerParameters, locale); case AreaStop -> new AreaStopsLayerBuilder(context.transitService(), layerParameters, locale); case VehicleRental -> new VehicleRentalPlacesLayerBuilder( @@ -166,7 +154,6 @@ private static LayerBuilder createLayerBuilder( public enum LayerType { Stop, - CurrentServiceWeekStop, Station, AreaStop, VehicleRental, diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/Predicates.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopPredicates.java similarity index 77% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/Predicates.java rename to src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopPredicates.java index 9b38587c22d..55d31c227a6 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/Predicates.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopPredicates.java @@ -9,7 +9,7 @@ import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.service.TransitService; -public class Predicates { +public class StopPredicates { public static final Predicate NO_FILTER = x -> true; @@ -28,4 +28,16 @@ public static Predicate currentServiceWeek(TransitService transitSe return !patternsInCurrentWeek.isEmpty(); }; } + + public static Predicate forType(FilterType type, TransitService transitService) { + return switch (type) { + case NONE -> NO_FILTER; + case CURRENT_TRIMET_SERVICE_WEEK -> currentServiceWeek(transitService); + }; + } + + public enum FilterType { + NONE, + CURRENT_TRIMET_SERVICE_WEEK, + } } diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java index a05851a90db..1a49c8e3696 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java @@ -22,8 +22,7 @@ public class StopsLayerBuilder extends LayerBuilder { public StopsLayerBuilder( TransitService transitService, LayerParameters layerParameters, - Locale locale, - Predicate filter + Locale locale ) { super( Map @@ -39,7 +38,7 @@ public StopsLayerBuilder( layerParameters.expansionFactor() ); this.transitService = transitService; - this.filter = filter; + this.filter = StopPredicates.forType(layerParameters.filterType(), transitService); } protected List getGeometries(Envelope query) { diff --git a/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java b/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java index cb849e0f0ac..b37cad615e5 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java +++ b/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java @@ -1,6 +1,7 @@ package org.opentripplanner.inspector.vector; import org.opentripplanner.apis.support.mapping.PropertyMapper; +import org.opentripplanner.ext.vectortiles.layers.stops.StopPredicates; /** * Configuration options for a single vector tile layer. @@ -53,4 +54,8 @@ default int cacheMaxSeconds() { default double expansionFactor() { return EXPANSION_FACTOR; } + + default StopPredicates.FilterType filterType() { + return StopPredicates.FilterType.NONE; + } } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java index d924a5a8328..70f99a099de 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java @@ -6,6 +6,7 @@ import static org.opentripplanner.inspector.vector.LayerParameters.MIN_ZOOM; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_0; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_5; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_6; import java.util.Collection; import java.util.List; @@ -13,6 +14,7 @@ import javax.annotation.Nullable; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.ext.vectortiles.VectorTilesResource.LayerType; +import org.opentripplanner.ext.vectortiles.layers.stops.StopPredicates; import org.opentripplanner.inspector.vector.LayerParameters; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; @@ -144,7 +146,18 @@ public static Layer mapLayer(NodeAdapter node) { "The value is a fraction of the tile size. If you are having problem with icons and " + "shapes being clipped at tile edges, then increase this number." ) - .asDouble(EXPANSION_FACTOR) + .asDouble(EXPANSION_FACTOR), + node + .of("filter") + .since(V2_6) + .summary("Reduce the result set of a layer further by a specific filter.") + .description( + """ + This is useful for when the schema of a layer, say stops, should remain unchanged but some + elements should not be included in the result. + """ + ) + .asEnum(StopPredicates.FilterType.NONE) ); } @@ -155,7 +168,8 @@ record Layer( int maxZoom, int minZoom, int cacheMaxSeconds, - double expansionFactor + double expansionFactor, + StopPredicates.FilterType filterType ) implements LayerParameters {} } From 924fce0b73103803a6ec8dd09f853e795cddd7ad Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 4 Sep 2024 21:51:48 +0200 Subject: [PATCH 13/47] Lowercase the enum name --- doc/user/examples/ibi/portland/router-config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user/examples/ibi/portland/router-config.json b/doc/user/examples/ibi/portland/router-config.json index 33810d7054e..8e392152dca 100644 --- a/doc/user/examples/ibi/portland/router-config.json +++ b/doc/user/examples/ibi/portland/router-config.json @@ -70,7 +70,7 @@ "maxZoom": 20, "minZoom": 14, "cacheMaxSeconds": 600, - "filter": "CURRENT_TRIMET_SERVICE_WEEK" + "filter": "current-trimet-service-week" }, { "name": "areaStops", From 0f5aaf66e8b2e148218ef3d9de92aa029664393a Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 5 Sep 2024 14:22:10 +0200 Subject: [PATCH 14/47] Add documentation --- .../{StopPredicates.java => LayerFilters.java} | 13 ++++++++++++- .../vectortiles/layers/stops/StopsLayerBuilder.java | 2 +- .../inspector/vector/LayerParameters.java | 6 +++--- .../config/routerconfig/VectorTileConfig.java | 6 +++--- 4 files changed, 19 insertions(+), 8 deletions(-) rename src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/{StopPredicates.java => LayerFilters.java} (76%) diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopPredicates.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFilters.java similarity index 76% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopPredicates.java rename to src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFilters.java index 55d31c227a6..ad0eafd9338 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopPredicates.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFilters.java @@ -9,10 +9,21 @@ import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.service.TransitService; -public class StopPredicates { +/** + * Predicates for filtering elements of vector tile layers. Currently only contains predicates + * for {@link RegularStop}. Once more types need to be filtered, this may need some refactoring. + */ +public class LayerFilters { + /** + * No filter is applied: all stops are included in the result. + */ public static final Predicate NO_FILTER = x -> true; + /** + * Returns a predicate which only includes stop which are visited by a pattern that is in the current + * TriMet service week, namely from Sunday to Sunday. + */ public static Predicate currentServiceWeek(TransitService transitService) { var serviceDate = LocalDate.now(transitService.getTimeZone()); var lastSunday = serviceDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY)); diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java index 1a49c8e3696..94497f83d0d 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java @@ -38,7 +38,7 @@ public StopsLayerBuilder( layerParameters.expansionFactor() ); this.transitService = transitService; - this.filter = StopPredicates.forType(layerParameters.filterType(), transitService); + this.filter = LayerFilters.forType(layerParameters.filterType(), transitService); } protected List getGeometries(Envelope query) { diff --git a/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java b/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java index b37cad615e5..c4e64f39ab8 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java +++ b/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java @@ -1,7 +1,7 @@ package org.opentripplanner.inspector.vector; import org.opentripplanner.apis.support.mapping.PropertyMapper; -import org.opentripplanner.ext.vectortiles.layers.stops.StopPredicates; +import org.opentripplanner.ext.vectortiles.layers.stops.LayerFilters; /** * Configuration options for a single vector tile layer. @@ -55,7 +55,7 @@ default double expansionFactor() { return EXPANSION_FACTOR; } - default StopPredicates.FilterType filterType() { - return StopPredicates.FilterType.NONE; + default LayerFilters.FilterType filterType() { + return LayerFilters.FilterType.NONE; } } diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java index 70f99a099de..1eb75c8d394 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java @@ -14,7 +14,7 @@ import javax.annotation.Nullable; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.ext.vectortiles.VectorTilesResource.LayerType; -import org.opentripplanner.ext.vectortiles.layers.stops.StopPredicates; +import org.opentripplanner.ext.vectortiles.layers.stops.LayerFilters; import org.opentripplanner.inspector.vector.LayerParameters; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; @@ -157,7 +157,7 @@ public static Layer mapLayer(NodeAdapter node) { elements should not be included in the result. """ ) - .asEnum(StopPredicates.FilterType.NONE) + .asEnum(LayerFilters.FilterType.NONE) ); } @@ -169,7 +169,7 @@ record Layer( int minZoom, int cacheMaxSeconds, double expansionFactor, - StopPredicates.FilterType filterType + LayerFilters.FilterType filterType ) implements LayerParameters {} } From 9303ee54a468b318d84c7d281c784c4a15cdb12f Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 5 Sep 2024 16:55:42 +0200 Subject: [PATCH 15/47] Add test --- .../layers/stops/LayerFiltersTest.java | 42 ++++++++++++++++++ .../layers/stops/LayerFilters.java | 28 +++++++++--- .../gtfs/PatternByServiceDatesFilter.java | 10 +---- .../gtfs/PatternByServiceDatesFilterTest.java | 38 +--------------- .../apis/gtfs/PatternTestModel.java | 44 +++++++++++++++++++ 5 files changed, 112 insertions(+), 50 deletions(-) create mode 100644 src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFiltersTest.java create mode 100644 src/test/java/org/opentripplanner/apis/gtfs/PatternTestModel.java diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFiltersTest.java b/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFiltersTest.java new file mode 100644 index 00000000000..6021662ab4b --- /dev/null +++ b/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFiltersTest.java @@ -0,0 +1,42 @@ +package org.opentripplanner.ext.vectortiles.layers.stops; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.time.LocalDate; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.opentripplanner.apis.gtfs.PatternTestModel; +import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model.network.TripPattern; +import org.opentripplanner.transit.model.site.RegularStop; + +class LayerFiltersTest { + + private static final RegularStop STOP = TransitModelForTest.of().stop("1").build(); + private static final LocalDate DATE = LocalDate.of(2024, 9, 5); + private static final TripPattern PATTERN = PatternTestModel.pattern(); + + @Test + void includeStopWithinServiceWeek() { + var predicate = LayerFilters.currentServiceWeek( + s -> List.of(PATTERN), + trip -> List.of(DATE), + () -> DATE + ); + + assertTrue(predicate.test(STOP)); + } + + @Test + void excludeOutsideServiceWeek() { + var inThreeWeeks = DATE.plusDays(21); + var predicate = LayerFilters.currentServiceWeek( + s -> List.of(PATTERN), + trip -> List.of(inThreeWeeks), + () -> DATE + ); + + assertFalse(predicate.test(STOP)); + } +} diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFilters.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFilters.java index ad0eafd9338..eddb4c6b745 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFilters.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFilters.java @@ -3,10 +3,16 @@ import java.time.DayOfWeek; import java.time.LocalDate; import java.time.temporal.TemporalAdjusters; +import java.util.Collection; +import java.util.List; +import java.util.function.Function; import java.util.function.Predicate; +import java.util.function.Supplier; import org.opentripplanner.apis.gtfs.PatternByServiceDatesFilter; import org.opentripplanner.apis.gtfs.model.LocalDateRange; +import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.RegularStop; +import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.service.TransitService; /** @@ -24,17 +30,24 @@ public class LayerFilters { * Returns a predicate which only includes stop which are visited by a pattern that is in the current * TriMet service week, namely from Sunday to Sunday. */ - public static Predicate currentServiceWeek(TransitService transitService) { - var serviceDate = LocalDate.now(transitService.getTimeZone()); + public static Predicate currentServiceWeek( + Function> getPatternsForStop, + Function> getServiceDatesForTrip, + Supplier nowSupplier + ) { + var serviceDate = nowSupplier.get(); var lastSunday = serviceDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY)); var nextSunday = serviceDate.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)).plusDays(1); + var filter = new PatternByServiceDatesFilter( new LocalDateRange(lastSunday, nextSunday), - transitService + // not used + route -> List.of(), + getServiceDatesForTrip ); return regularStop -> { - var patterns = transitService.getPatternsForStop(regularStop); + var patterns = getPatternsForStop.apply(regularStop); var patternsInCurrentWeek = filter.filterPatterns(patterns); return !patternsInCurrentWeek.isEmpty(); }; @@ -43,7 +56,12 @@ public static Predicate currentServiceWeek(TransitService transitSe public static Predicate forType(FilterType type, TransitService transitService) { return switch (type) { case NONE -> NO_FILTER; - case CURRENT_TRIMET_SERVICE_WEEK -> currentServiceWeek(transitService); + case CURRENT_TRIMET_SERVICE_WEEK -> currentServiceWeek( + transitService::getPatternsForStop, + trip -> + transitService.getCalendarService().getServiceDatesForServiceId(trip.getServiceId()), + () -> LocalDate.now(transitService.getTimeZone()) + ); }; } diff --git a/src/main/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilter.java b/src/main/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilter.java index fc980da4380..8cf72bf9365 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilter.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilter.java @@ -29,7 +29,7 @@ public class PatternByServiceDatesFilter { * This method is not private to enable unit testing. *

*/ - PatternByServiceDatesFilter( + public PatternByServiceDatesFilter( LocalDateRange range, Function> getPatternsForRoute, Function> getServiceDatesForTrip @@ -56,14 +56,6 @@ public PatternByServiceDatesFilter( ); } - public PatternByServiceDatesFilter(LocalDateRange range, TransitService transitService) { - this( - range, - transitService::getPatternsForRoute, - trip -> transitService.getCalendarService().getServiceDatesForServiceId(trip.getServiceId()) - ); - } - /** * Filter the patterns by the service dates that it operates on. */ diff --git a/src/test/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilterTest.java b/src/test/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilterTest.java index f01bac12006..934bc5a9b1e 100644 --- a/src/test/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilterTest.java +++ b/src/test/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilterTest.java @@ -6,7 +6,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.opentripplanner.apis.gtfs.PatternByServiceDatesFilterTest.FilterExpectation.NOT_REMOVED; import static org.opentripplanner.apis.gtfs.PatternByServiceDatesFilterTest.FilterExpectation.REMOVED; -import static org.opentripplanner.transit.model._data.TransitModelForTest.id; +import static org.opentripplanner.apis.gtfs.PatternTestModel.ROUTE_1; import java.time.LocalDate; import java.util.List; @@ -14,51 +14,17 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.apis.gtfs.model.LocalDateRange; -import org.opentripplanner.transit.model._data.TransitModelForTest; -import org.opentripplanner.transit.model.framework.FeedScopedId; -import org.opentripplanner.transit.model.network.Route; -import org.opentripplanner.transit.model.network.StopPattern; import org.opentripplanner.transit.model.network.TripPattern; -import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.model.timetable.ScheduledTripTimes; -import org.opentripplanner.transit.model.timetable.Trip; -import org.opentripplanner.transit.service.StopModel; class PatternByServiceDatesFilterTest { - private static final Route ROUTE_1 = TransitModelForTest.route("1").build(); - private static final FeedScopedId SERVICE_ID = id("service"); - private static final Trip TRIP = TransitModelForTest - .trip("t1") - .withRoute(ROUTE_1) - .withServiceId(SERVICE_ID) - .build(); - private static final TransitModelForTest MODEL = new TransitModelForTest(StopModel.of()); - private static final RegularStop STOP_1 = MODEL.stop("1").build(); - private static final StopPattern STOP_PATTERN = TransitModelForTest.stopPattern(STOP_1, STOP_1); - private static final TripPattern PATTERN_1 = pattern(); + private static final TripPattern PATTERN_1 = PatternTestModel.pattern(); enum FilterExpectation { REMOVED, NOT_REMOVED, } - private static TripPattern pattern() { - var pattern = TransitModelForTest - .tripPattern("1", ROUTE_1) - .withStopPattern(STOP_PATTERN) - .build(); - - var tt = ScheduledTripTimes - .of() - .withTrip(TRIP) - .withArrivalTimes("10:00 10:05") - .withDepartureTimes("10:00 10:05") - .build(); - pattern.add(tt); - return pattern; - } - static List invalidRangeCases() { return List.of( Arguments.of(null, null), diff --git a/src/test/java/org/opentripplanner/apis/gtfs/PatternTestModel.java b/src/test/java/org/opentripplanner/apis/gtfs/PatternTestModel.java new file mode 100644 index 00000000000..fda75d9e174 --- /dev/null +++ b/src/test/java/org/opentripplanner/apis/gtfs/PatternTestModel.java @@ -0,0 +1,44 @@ +package org.opentripplanner.apis.gtfs; + +import static org.opentripplanner.transit.model._data.TransitModelForTest.id; + +import org.opentripplanner.transit.model._data.TransitModelForTest; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.network.Route; +import org.opentripplanner.transit.model.network.StopPattern; +import org.opentripplanner.transit.model.network.TripPattern; +import org.opentripplanner.transit.model.site.RegularStop; +import org.opentripplanner.transit.model.timetable.ScheduledTripTimes; +import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.transit.service.StopModel; + +public class PatternTestModel { + + public static final Route ROUTE_1 = TransitModelForTest.route("1").build(); + + private static final FeedScopedId SERVICE_ID = id("service"); + private static final Trip TRIP = TransitModelForTest + .trip("t1") + .withRoute(ROUTE_1) + .withServiceId(SERVICE_ID) + .build(); + private static final TransitModelForTest MODEL = new TransitModelForTest(StopModel.of()); + private static final RegularStop STOP_1 = MODEL.stop("1").build(); + private static final StopPattern STOP_PATTERN = TransitModelForTest.stopPattern(STOP_1, STOP_1); + + public static TripPattern pattern() { + var pattern = TransitModelForTest + .tripPattern("1", ROUTE_1) + .withStopPattern(STOP_PATTERN) + .build(); + + var tt = ScheduledTripTimes + .of() + .withTrip(TRIP) + .withArrivalTimes("10:00 10:05") + .withDepartureTimes("10:00 10:05") + .build(); + pattern.add(tt); + return pattern; + } +} From d5583b843c5d9730236acfb08788255abcb147f4 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 9 Sep 2024 09:37:12 +0200 Subject: [PATCH 16/47] Apply suggestions from code review Co-authored-by: Henrik Abrahamsson <127481124+habrahamsson-skanetrafiken@users.noreply.github.com> --- .../moduletests/cancellation/CancellationDeletionTest.java | 6 +++--- .../updater/trip/moduletests/delay/DelayedTest.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java index f619aceef78..266b85024e4 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java @@ -76,9 +76,9 @@ void cancelingAddedTrip(ScheduleRelationship relationship, RealTimeState state) ScheduleRelationship.ADDED, TIME_ZONE ) - .addStopTime(STOP_A1.getId().getId(), 30) - .addStopTime(STOP_B1.getId().getId(), 40) - .addStopTime(STOP_C1.getId().getId(), 55) + .addStopTime(STOP_A1_ID, 30) + .addStopTime(STOP_B1_ID, 40) + .addStopTime(STOP_C1_ID, 55) .build(); assertSuccess(env.applyTripUpdate(update, DIFFERENTIAL)); diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java index 5b2f5326599..42f67ce1e02 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java @@ -53,7 +53,7 @@ void singleStopDelay() { assertEquals( "SCHEDULED | A1 0:00:10 0:00:11 | B1 0:00:20 0:00:21", - env.getScheduledTimetable(id(TRIP_1_ID)) + env.getScheduledTimetable(TRIP_1_ID) ); assertEquals( "UPDATED | A1 [ND] 0:00:10 0:00:11 | B1 0:00:21 0:00:22", From c97d90a2bff2948d4a62e253fc1fe9fb0b2a6dd6 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 9 Sep 2024 10:14:15 +0200 Subject: [PATCH 17/47] Improve handling of IDs --- .../trip/moduletests/delay/DelayedTest.java | 10 +++--- .../trip/moduletests/delay/SkippedTest.java | 33 +++++++++---------- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java index 42f67ce1e02..fc1051425f1 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java @@ -68,9 +68,7 @@ void singleStopDelay() { void complexDelay() { var env = RealtimeTestEnvironment.gtfs().withTrip2().build(); - var tripId = TRIP_2_ID; - - var tripUpdate = new TripUpdateBuilder(tripId, SERVICE_DATE, SCHEDULED, TIME_ZONE) + var tripUpdate = new TripUpdateBuilder(TRIP_2_ID, SERVICE_DATE, SCHEDULED, TIME_ZONE) .addDelayedStopTime(0, 0) .addDelayedStopTime(1, 60, 80) .addDelayedStopTime(2, 90, 90) @@ -80,7 +78,7 @@ void complexDelay() { var snapshot = env.getTimetableSnapshot(); - var trip2 = env.getTransitService().getTripForId(id(tripId)); + var trip2 = env.getTransitService().getTripForId(id(TRIP_2_ID)); var originalTripPattern = env.getTransitService().getPatternForTrip(trip2); var originalTimetableForToday = snapshot.resolve(originalTripPattern, SERVICE_DATE); @@ -88,7 +86,7 @@ void complexDelay() { assertNotSame(originalTimetableForToday, originalTimetableScheduled); - final int originalTripIndexScheduled = originalTimetableScheduled.getTripIndex(tripId); + final int originalTripIndexScheduled = originalTimetableScheduled.getTripIndex(TRIP_2_ID); assertTrue( originalTripIndexScheduled > -1, "Original trip should be found in scheduled time table" @@ -102,7 +100,7 @@ void complexDelay() { ); assertEquals(RealTimeState.SCHEDULED, originalTripTimesScheduled.getRealTimeState()); - final int originalTripIndexForToday = originalTimetableForToday.getTripIndex(tripId); + final int originalTripIndexForToday = originalTimetableForToday.getTripIndex(TRIP_2_ID); assertTrue( originalTripIndexForToday > -1, "Original trip should be found in time table for service date" diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java index 7658ac4d5ad..04820c02fce 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java @@ -11,7 +11,6 @@ import static org.opentripplanner.updater.trip.UpdateIncrementality.DIFFERENTIAL; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.timetable.RealTimeState; import org.opentripplanner.transit.model.timetable.TripTimesStringBuilder; import org.opentripplanner.updater.trip.RealtimeTestConstants; @@ -35,10 +34,9 @@ void scheduledTripWithSkippedAndScheduled() { assertSuccess(env.applyTripUpdate(tripUpdate)); - var trip2Id = id(TRIP_2_ID); - assertOriginalTripPatternIsDeleted(env, trip2Id); + assertOriginalTripPatternIsDeleted(env, TRIP_2_ID); - assertNewTripTimesIsUpdated(env, trip2Id); + assertNewTripTimesIsUpdated(env, TRIP_2_ID); assertEquals( "UPDATED | A1 0:01 0:01:01 | B1 [C] 0:01:52 0:01:58 | C1 0:02:50 0:02:51", @@ -58,9 +56,8 @@ void scheduledTripWithSkippedAndScheduled() { @Test void scheduledTripWithPreviouslySkipped() { var env = RealtimeTestEnvironment.gtfs().withTrip2().build(); - var tripId = id(TRIP_2_ID); - var tripUpdate = new TripUpdateBuilder(tripId.getId(), SERVICE_DATE, SCHEDULED, TIME_ZONE) + var tripUpdate = new TripUpdateBuilder(TRIP_2_ID, SERVICE_DATE, SCHEDULED, TIME_ZONE) .addDelayedStopTime(0, 0) .addSkippedStop(1) .addDelayedStopTime(2, 90) @@ -69,7 +66,7 @@ void scheduledTripWithPreviouslySkipped() { assertSuccess(env.applyTripUpdate(tripUpdate, DIFFERENTIAL)); // Create update to the same trip but now the skipped stop is no longer skipped - var scheduledBuilder = new TripUpdateBuilder(tripId.getId(), SERVICE_DATE, SCHEDULED, TIME_ZONE) + var scheduledBuilder = new TripUpdateBuilder(TRIP_2_ID, SERVICE_DATE, SCHEDULED, TIME_ZONE) .addDelayedStopTime(0, 0) .addDelayedStopTime(1, 50) .addDelayedStopTime(2, 90); @@ -83,17 +80,17 @@ void scheduledTripWithPreviouslySkipped() { // stoptime updates have gone through var snapshot = env.getTimetableSnapshot(); - assertNull(snapshot.getRealtimeAddedTripPattern(tripId, SERVICE_DATE)); + assertNull(snapshot.getRealtimeAddedTripPattern(id(TRIP_2_ID), SERVICE_DATE)); - assertNewTripTimesIsUpdated(env, tripId); + assertNewTripTimesIsUpdated(env, TRIP_2_ID); assertEquals( "SCHEDULED | A1 0:01 0:01:01 | B1 0:01:10 0:01:11 | C1 0:01:20 0:01:21", - env.getScheduledTimetable(tripId) + env.getScheduledTimetable(TRIP_2_ID) ); assertEquals( "UPDATED | A1 0:01 0:01:01 | B1 0:02 0:02:01 | C1 0:02:50 0:02:51", - env.getRealtimeTimetable(tripId, SERVICE_DATE) + env.getRealtimeTimetable(id(TRIP_2_ID), SERVICE_DATE) ); } @@ -104,9 +101,9 @@ void scheduledTripWithPreviouslySkipped() { void skippedNoData() { var env = RealtimeTestEnvironment.gtfs().withTrip2().build(); - final FeedScopedId tripId = id(TRIP_2_ID); + String tripId = TRIP_2_ID; - var tripUpdate = new TripUpdateBuilder(tripId.getId(), SERVICE_DATE, SCHEDULED, TIME_ZONE) + var tripUpdate = new TripUpdateBuilder(tripId, SERVICE_DATE, SCHEDULED, TIME_ZONE) .addNoDataStop(0) .addSkippedStop(1) .addNoDataStop(2) @@ -120,15 +117,15 @@ void skippedNoData() { assertEquals( "UPDATED | A1 [ND] 0:01 0:01:01 | B1 [C] 0:01:10 0:01:11 | C1 [ND] 0:01:20 0:01:21", - env.getRealtimeTimetable(tripId.getId()) + env.getRealtimeTimetable(tripId) ); } private static void assertOriginalTripPatternIsDeleted( RealtimeTestEnvironment env, - FeedScopedId tripId + String tripId ) { - var trip = env.getTransitService().getTripForId(tripId); + var trip = env.getTransitService().getTripForId(id(tripId)); var originalTripPattern = env.getTransitService().getPatternForTrip(trip); var snapshot = env.getTimetableSnapshot(); var originalTimetableForToday = snapshot.resolve(originalTripPattern, SERVICE_DATE); @@ -172,9 +169,9 @@ private static void assertOriginalTripPatternIsDeleted( private static void assertNewTripTimesIsUpdated( RealtimeTestEnvironment env, - FeedScopedId tripId + String tripId ) { - var trip = env.getTransitService().getTripForId(tripId); + var trip = env.getTransitService().getTripForId(id(tripId)); var originalTripPattern = env.getTransitService().getPatternForTrip(trip); var snapshot = env.getTimetableSnapshot(); var originalTimetableForToday = snapshot.resolve(originalTripPattern, SERVICE_DATE); From 049e0de427a75980d1496dc5b7294bc81eb955ef Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 9 Sep 2024 10:15:05 +0200 Subject: [PATCH 18/47] Remove un-needed test trip --- .../trip/moduletests/cancellation/CancellationDeletionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java index 266b85024e4..775bdf4703a 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java @@ -67,7 +67,7 @@ void cancelledTrip(ScheduleRelationship relationship, RealTimeState state) { @ParameterizedTest @MethodSource("cases") void cancelingAddedTrip(ScheduleRelationship relationship, RealTimeState state) { - var env = RealtimeTestEnvironment.gtfs().withTrip1().build(); + var env = RealtimeTestEnvironment.gtfs().build(); var addedTripId = "added-trip"; // First add ADDED trip var update = new TripUpdateBuilder( From a5ff803701ecad9f4d4dcd9431ef5cf150991ce7 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 9 Sep 2024 10:20:55 +0200 Subject: [PATCH 19/47] Format code --- .../updater/trip/moduletests/delay/SkippedTest.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java index 04820c02fce..05910603ff3 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java @@ -167,10 +167,7 @@ private static void assertOriginalTripPatternIsDeleted( assertEquals(RealTimeState.DELETED, originalTripTimesForToday.getRealTimeState()); } - private static void assertNewTripTimesIsUpdated( - RealtimeTestEnvironment env, - String tripId - ) { + private static void assertNewTripTimesIsUpdated(RealtimeTestEnvironment env, String tripId) { var trip = env.getTransitService().getTripForId(id(tripId)); var originalTripPattern = env.getTransitService().getPatternForTrip(trip); var snapshot = env.getTimetableSnapshot(); From a09f817f5c5a92394cd045c03ab82e09e2040050 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 10 Sep 2024 14:35:04 +0200 Subject: [PATCH 20/47] Extra records for realtime trip input --- .../trip/RealtimeTestEnvironmentBuilder.java | 44 ++++++++++--------- .../updater/trip/RealtimeTripInput.java | 6 +++ .../updater/trip/StopCall.java | 5 +++ 3 files changed, 34 insertions(+), 21 deletions(-) create mode 100644 src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java create mode 100644 src/test/java/org/opentripplanner/updater/trip/StopCall.java diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java index fceaa31b8df..1249e6f56b4 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java @@ -11,9 +11,7 @@ import org.opentripplanner.model.calendar.CalendarServiceData; import org.opentripplanner.transit.model._data.TransitModelForTest; import org.opentripplanner.transit.model.framework.Deduplicator; -import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.TripPattern; -import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.timetable.Trip; import org.opentripplanner.transit.model.timetable.TripOnServiceDate; @@ -33,9 +31,11 @@ RealtimeTestEnvironmentBuilder withSourceType(RealtimeTestEnvironment.SourceType public RealtimeTestEnvironmentBuilder withTrip1() { createTrip( - TRIP_1_ID, - ROUTE_1, - List.of(new StopCall(STOP_A1, 10, 11), new StopCall(STOP_B1, 20, 21)) + new RealtimeTripInput( + TRIP_1_ID, + ROUTE_1, + List.of(new StopCall(STOP_A1, 10, 11), new StopCall(STOP_B1, 20, 21)) + ) ); transitModel.index(); return this; @@ -43,12 +43,14 @@ public RealtimeTestEnvironmentBuilder withTrip1() { public RealtimeTestEnvironmentBuilder withTrip2() { createTrip( - TRIP_2_ID, - ROUTE_1, - List.of( - new StopCall(STOP_A1, 60, 61), - new StopCall(STOP_B1, 70, 71), - new StopCall(STOP_C1, 80, 81) + new RealtimeTripInput( + TRIP_2_ID, + ROUTE_1, + List.of( + new StopCall(STOP_A1, 60, 61), + new StopCall(STOP_B1, 70, 71), + new StopCall(STOP_C1, 80, 81) + ) ) ); @@ -72,11 +74,11 @@ public RealtimeTestEnvironment build() { return new RealtimeTestEnvironment(sourceType, transitModel); } - private Trip createTrip(String id, Route route, List stops) { + private Trip createTrip(RealtimeTripInput tripInput) { var trip = Trip - .of(id(id)) - .withRoute(route) - .withHeadsign(I18NString.of("Headsign of %s".formatted(id))) + .of(id(tripInput.id())) + .withRoute(tripInput.route()) + .withHeadsign(I18NString.of("Headsign of %s".formatted(tripInput.id()))) .withServiceId(SERVICE_ID) .build(); @@ -89,9 +91,9 @@ private Trip createTrip(String id, Route route, List stops) { transitModel.addTripOnServiceDate(tripOnServiceDate.getId(), tripOnServiceDate); var stopTimes = IntStream - .range(0, stops.size()) + .range(0, tripInput.stops().size()) .mapToObj(i -> { - var stop = stops.get(i); + var stop = tripInput.stops().get(i); return createStopTime(trip, i, stop.stop(), stop.arrivalTime(), stop.departureTime()); }) .toList(); @@ -99,8 +101,10 @@ private Trip createTrip(String id, Route route, List stops) { TripTimes tripTimes = TripTimesFactory.tripTimes(trip, stopTimes, null); final TripPattern pattern = TransitModelForTest - .tripPattern(id + "Pattern", route) - .withStopPattern(TransitModelForTest.stopPattern(stops.stream().map(StopCall::stop).toList())) + .tripPattern(tripInput.id() + "Pattern", tripInput.route()) + .withStopPattern( + TransitModelForTest.stopPattern(tripInput.stops().stream().map(StopCall::stop).toList()) + ) .build(); pattern.add(tripTimes); @@ -124,6 +128,4 @@ private static StopTime createStopTime( st.setDepartureTime(departureTime); return st; } - - private record StopCall(RegularStop stop, int arrivalTime, int departureTime) {} } diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java new file mode 100644 index 00000000000..772295eaeeb --- /dev/null +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java @@ -0,0 +1,6 @@ +package org.opentripplanner.updater.trip; + +import java.util.List; +import org.opentripplanner.transit.model.network.Route; + +record RealtimeTripInput(String id, Route route, List stops) {} diff --git a/src/test/java/org/opentripplanner/updater/trip/StopCall.java b/src/test/java/org/opentripplanner/updater/trip/StopCall.java new file mode 100644 index 00000000000..164b2420c87 --- /dev/null +++ b/src/test/java/org/opentripplanner/updater/trip/StopCall.java @@ -0,0 +1,5 @@ +package org.opentripplanner.updater.trip; + +import org.opentripplanner.transit.model.site.RegularStop; + +record StopCall(RegularStop stop, int arrivalTime, int departureTime) {} From 68ef56d06954abe9189f50de2975c91c32a16f7e Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 10 Sep 2024 14:51:58 +0200 Subject: [PATCH 21/47] Extract more builders for test trips --- .../trip/RealtimeTestEnvironmentBuilder.java | 25 +++++++-------- .../updater/trip/RealtimeTripInput.java | 32 ++++++++++++++++++- 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java index 1249e6f56b4..a884bf573a8 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java @@ -31,11 +31,11 @@ RealtimeTestEnvironmentBuilder withSourceType(RealtimeTestEnvironment.SourceType public RealtimeTestEnvironmentBuilder withTrip1() { createTrip( - new RealtimeTripInput( - TRIP_1_ID, - ROUTE_1, - List.of(new StopCall(STOP_A1, 10, 11), new StopCall(STOP_B1, 20, 21)) - ) + RealtimeTripInput + .of(TRIP_1_ID) + .addStop(STOP_A1, "0:00:10", "0:00:11") + .addStop(STOP_B1, "0:00:20", "0:00:21") + .build() ); transitModel.index(); return this; @@ -43,15 +43,12 @@ public RealtimeTestEnvironmentBuilder withTrip1() { public RealtimeTestEnvironmentBuilder withTrip2() { createTrip( - new RealtimeTripInput( - TRIP_2_ID, - ROUTE_1, - List.of( - new StopCall(STOP_A1, 60, 61), - new StopCall(STOP_B1, 70, 71), - new StopCall(STOP_C1, 80, 81) - ) - ) + RealtimeTripInput + .of(TRIP_2_ID) + .addStop(STOP_A1, "0:01:00", "0:01:01") + .addStop(STOP_B1, "0:01:10", "0:01:11") + .addStop(STOP_C1, "0:01:20", "0:01:21") + .build() ); transitModel.index(); diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java index 772295eaeeb..92b6c5c3aa3 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java @@ -1,6 +1,36 @@ package org.opentripplanner.updater.trip; +import java.util.ArrayList; import java.util.List; +import org.opentripplanner.framework.time.TimeUtils; import org.opentripplanner.transit.model.network.Route; +import org.opentripplanner.transit.model.site.RegularStop; -record RealtimeTripInput(String id, Route route, List stops) {} +record RealtimeTripInput(String id, Route route, List stops) { + static RealtimeTripInputBuilder of(String id) { + return new RealtimeTripInputBuilder(id); + } + + static class RealtimeTripInputBuilder implements RealtimeTestConstants { + + private final String id; + private final List stops = new ArrayList<>(); + // can be made configurable if needed + private final Route route = ROUTE_1; + + RealtimeTripInputBuilder(String id) { + this.id = id; + } + + RealtimeTripInputBuilder addStop(RegularStop stopId, String arrivalTime, String departureTime) { + this.stops.add( + new StopCall(stopId, TimeUtils.time(arrivalTime), TimeUtils.time(departureTime)) + ); + return this; + } + + RealtimeTripInput build() { + return new RealtimeTripInput(id, route, stops); + } + } +} From d872b3eeb99d7a9105981c027083b14adf23a5ec Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 10 Sep 2024 15:11:34 +0200 Subject: [PATCH 22/47] Replace withTrip2() --- .../ext/siri/SiriTimetableSnapshotSourceTest.java | 12 ++++++++++-- .../trip/RealtimeTestEnvironmentBuilder.java | 11 ++--------- .../updater/trip/RealtimeTripInput.java | 14 +++++++++----- .../trip/moduletests/delay/DelayedTest.java | 9 ++++++++- .../trip/moduletests/delay/SkippedTest.java | 14 +++++++++++--- 5 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java index 8272d0c43af..e94ec1073a6 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java @@ -9,9 +9,17 @@ import org.opentripplanner.updater.spi.UpdateError; import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; +import org.opentripplanner.updater.trip.RealtimeTripInput; class SiriTimetableSnapshotSourceTest implements RealtimeTestConstants { + private static final RealtimeTripInput TRIP2_INPUT = RealtimeTripInput + .of(TRIP_2_ID) + .addStop(STOP_A1, "0:01:00", "0:01:01") + .addStop(STOP_B1, "0:01:10", "0:01:11") + .addStop(STOP_C1, "0:01:20", "0:01:21") + .build(); + @Test void testCancelTrip() { var env = RealtimeTestEnvironment.siri().withTrip1().build(); @@ -245,7 +253,7 @@ void testChangeQuay() { @Test void testCancelStop() { - var env = RealtimeTestEnvironment.siri().withTrip2().build(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP2_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withDatedVehicleJourneyRef(TRIP_2_ID) @@ -362,7 +370,7 @@ void testNegativeHopTime() { @Test void testNegativeDwellTime() { - var env = RealtimeTestEnvironment.siri().withTrip2().build(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP2_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withDatedVehicleJourneyRef(TRIP_2_ID) diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java index a884bf573a8..1887989bfbd 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java @@ -41,15 +41,8 @@ public RealtimeTestEnvironmentBuilder withTrip1() { return this; } - public RealtimeTestEnvironmentBuilder withTrip2() { - createTrip( - RealtimeTripInput - .of(TRIP_2_ID) - .addStop(STOP_A1, "0:01:00", "0:01:01") - .addStop(STOP_B1, "0:01:10", "0:01:11") - .addStop(STOP_C1, "0:01:20", "0:01:21") - .build() - ); + public RealtimeTestEnvironmentBuilder addTrip(RealtimeTripInput trip) { + createTrip(trip); transitModel.index(); return this; diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java index 92b6c5c3aa3..51af39aafcd 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java @@ -6,12 +6,12 @@ import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.site.RegularStop; -record RealtimeTripInput(String id, Route route, List stops) { - static RealtimeTripInputBuilder of(String id) { +public record RealtimeTripInput(String id, Route route, List stops) { + public static RealtimeTripInputBuilder of(String id) { return new RealtimeTripInputBuilder(id); } - static class RealtimeTripInputBuilder implements RealtimeTestConstants { + public static class RealtimeTripInputBuilder implements RealtimeTestConstants { private final String id; private final List stops = new ArrayList<>(); @@ -22,14 +22,18 @@ static class RealtimeTripInputBuilder implements RealtimeTestConstants { this.id = id; } - RealtimeTripInputBuilder addStop(RegularStop stopId, String arrivalTime, String departureTime) { + public RealtimeTripInputBuilder addStop( + RegularStop stopId, + String arrivalTime, + String departureTime + ) { this.stops.add( new StopCall(stopId, TimeUtils.time(arrivalTime), TimeUtils.time(departureTime)) ); return this; } - RealtimeTripInput build() { + public RealtimeTripInput build() { return new RealtimeTripInput(id, route, stops); } } diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java index fc1051425f1..49fb792451d 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java @@ -12,6 +12,7 @@ import org.opentripplanner.transit.model.timetable.RealTimeState; import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; +import org.opentripplanner.updater.trip.RealtimeTripInput; import org.opentripplanner.updater.trip.TripUpdateBuilder; /** @@ -66,7 +67,13 @@ void singleStopDelay() { */ @Test void complexDelay() { - var env = RealtimeTestEnvironment.gtfs().withTrip2().build(); + var tripInput = RealtimeTripInput + .of(TRIP_2_ID) + .addStop(STOP_A1, "0:01:00", "0:01:01") + .addStop(STOP_B1, "0:01:10", "0:01:11") + .addStop(STOP_C1, "0:01:20", "0:01:21") + .build(); + var env = RealtimeTestEnvironment.gtfs().addTrip(tripInput).build(); var tripUpdate = new TripUpdateBuilder(TRIP_2_ID, SERVICE_DATE, SCHEDULED, TIME_ZONE) .addDelayedStopTime(0, 0) diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java index 05910603ff3..16e201ed515 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java @@ -15,6 +15,7 @@ import org.opentripplanner.transit.model.timetable.TripTimesStringBuilder; import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; +import org.opentripplanner.updater.trip.RealtimeTripInput; import org.opentripplanner.updater.trip.TripUpdateBuilder; /** @@ -22,9 +23,16 @@ */ class SkippedTest implements RealtimeTestConstants { + private static final RealtimeTripInput TRIP_INPUT = RealtimeTripInput + .of(TRIP_2_ID) + .addStop(STOP_A1, "0:01:00", "0:01:01") + .addStop(STOP_B1, "0:01:10", "0:01:11") + .addStop(STOP_C1, "0:01:20", "0:01:21") + .build(); + @Test void scheduledTripWithSkippedAndScheduled() { - var env = RealtimeTestEnvironment.gtfs().withTrip2().build(); + var env = RealtimeTestEnvironment.gtfs().addTrip(TRIP_INPUT).build(); var tripUpdate = new TripUpdateBuilder(TRIP_2_ID, SERVICE_DATE, SCHEDULED, TIME_ZONE) .addDelayedStopTime(0, 0) @@ -55,7 +63,7 @@ void scheduledTripWithSkippedAndScheduled() { */ @Test void scheduledTripWithPreviouslySkipped() { - var env = RealtimeTestEnvironment.gtfs().withTrip2().build(); + var env = RealtimeTestEnvironment.gtfs().addTrip(TRIP_INPUT).build(); var tripUpdate = new TripUpdateBuilder(TRIP_2_ID, SERVICE_DATE, SCHEDULED, TIME_ZONE) .addDelayedStopTime(0, 0) @@ -99,7 +107,7 @@ void scheduledTripWithPreviouslySkipped() { */ @Test void skippedNoData() { - var env = RealtimeTestEnvironment.gtfs().withTrip2().build(); + var env = RealtimeTestEnvironment.gtfs().addTrip(TRIP_INPUT).build(); String tripId = TRIP_2_ID; From 966a7c9f9797aa2ad2f9b8e5f696fa1d27c7ce49 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 10 Sep 2024 16:40:15 +0200 Subject: [PATCH 23/47] Move filter class into transit.service --- .../layers/stops/LayerFilters.java | 2 +- .../apis/gtfs/datafetchers/QueryTypeImpl.java | 7 ++++-- .../apis/gtfs/datafetchers/RouteImpl.java | 7 ++++-- .../filter/PatternByDateFilterUtil.java | 23 +++++++++++++++++++ .../service}/PatternByServiceDatesFilter.java | 15 +----------- .../PatternByServiceDatesFilterTest.java | 7 +++--- 6 files changed, 39 insertions(+), 22 deletions(-) create mode 100644 src/main/java/org/opentripplanner/apis/gtfs/support/filter/PatternByDateFilterUtil.java rename src/main/java/org/opentripplanner/{apis/gtfs => transit/service}/PatternByServiceDatesFilter.java (82%) rename src/test/java/org/opentripplanner/{apis/gtfs => transit/service}/PatternByServiceDatesFilterTest.java (92%) diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFilters.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFilters.java index eddb4c6b745..54e4052ee63 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFilters.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFilters.java @@ -8,11 +8,11 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; -import org.opentripplanner.apis.gtfs.PatternByServiceDatesFilter; import org.opentripplanner.apis.gtfs.model.LocalDateRange; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.transit.service.PatternByServiceDatesFilter; import org.opentripplanner.transit.service.TransitService; /** diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java index 0e70c13074b..d5551a9b902 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java @@ -27,12 +27,12 @@ import org.locationtech.jts.geom.Envelope; import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.apis.gtfs.GraphQLUtils; -import org.opentripplanner.apis.gtfs.PatternByServiceDatesFilter; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLQueryTypeStopsByRadiusArgs; import org.opentripplanner.apis.gtfs.mapping.routerequest.LegacyRouteRequestMapper; import org.opentripplanner.apis.gtfs.mapping.routerequest.RouteRequestMapper; +import org.opentripplanner.apis.gtfs.support.filter.PatternByDateFilterUtil; import org.opentripplanner.apis.gtfs.support.time.LocalDateRangeUtil; import org.opentripplanner.ext.fares.impl.DefaultFareService; import org.opentripplanner.ext.fares.impl.GtfsFaresService; @@ -615,7 +615,10 @@ public DataFetcher> routes() { } if (LocalDateRangeUtil.hasServiceDateFilter(args.getGraphQLServiceDates())) { - var filter = new PatternByServiceDatesFilter(args.getGraphQLServiceDates(), transitService); + var filter = PatternByDateFilterUtil.ofGraphQL( + args.getGraphQLServiceDates(), + transitService + ); routeStream = filter.filterRoutes(routeStream).stream(); } return routeStream.toList(); diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteImpl.java index a3f557951f0..ae6acb0a297 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/RouteImpl.java @@ -9,12 +9,12 @@ import java.util.stream.Collectors; import org.opentripplanner.apis.gtfs.GraphQLRequestContext; import org.opentripplanner.apis.gtfs.GraphQLUtils; -import org.opentripplanner.apis.gtfs.PatternByServiceDatesFilter; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLBikesAllowed; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes.GraphQLTransitMode; import org.opentripplanner.apis.gtfs.mapping.BikesAllowedMapper; +import org.opentripplanner.apis.gtfs.support.filter.PatternByDateFilterUtil; import org.opentripplanner.apis.gtfs.support.time.LocalDateRangeUtil; import org.opentripplanner.routing.alertpatch.EntitySelector; import org.opentripplanner.routing.alertpatch.TransitAlert; @@ -183,7 +183,10 @@ public DataFetcher> patterns() { var args = new GraphQLTypes.GraphQLRoutePatternsArgs(environment.getArguments()); if (LocalDateRangeUtil.hasServiceDateFilter(args.getGraphQLServiceDates())) { - var filter = new PatternByServiceDatesFilter(args.getGraphQLServiceDates(), transitService); + var filter = PatternByDateFilterUtil.ofGraphQL( + args.getGraphQLServiceDates(), + transitService + ); return filter.filterPatterns(patterns); } else { return patterns; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/support/filter/PatternByDateFilterUtil.java b/src/main/java/org/opentripplanner/apis/gtfs/support/filter/PatternByDateFilterUtil.java new file mode 100644 index 00000000000..204cdbd0886 --- /dev/null +++ b/src/main/java/org/opentripplanner/apis/gtfs/support/filter/PatternByDateFilterUtil.java @@ -0,0 +1,23 @@ +package org.opentripplanner.apis.gtfs.support.filter; + +import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; +import org.opentripplanner.apis.gtfs.model.LocalDateRange; +import org.opentripplanner.transit.service.PatternByServiceDatesFilter; +import org.opentripplanner.transit.service.TransitService; + +/** + * Utility methods for instantiating a {@link PatternByServiceDatesFilter}/ + */ +public class PatternByDateFilterUtil { + + public static PatternByServiceDatesFilter ofGraphQL( + GraphQLTypes.GraphQLLocalDateRangeInput range, + TransitService transitService + ) { + return new PatternByServiceDatesFilter( + new LocalDateRange(range.getGraphQLStart(), range.getGraphQLEnd()), + transitService::getPatternsForRoute, + trip -> transitService.getCalendarService().getServiceDatesForServiceId(trip.getServiceId()) + ); + } +} diff --git a/src/main/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilter.java b/src/main/java/org/opentripplanner/transit/service/PatternByServiceDatesFilter.java similarity index 82% rename from src/main/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilter.java rename to src/main/java/org/opentripplanner/transit/service/PatternByServiceDatesFilter.java index 8cf72bf9365..30c501af4a0 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilter.java +++ b/src/main/java/org/opentripplanner/transit/service/PatternByServiceDatesFilter.java @@ -1,16 +1,14 @@ -package org.opentripplanner.apis.gtfs; +package org.opentripplanner.transit.service; import java.time.LocalDate; import java.util.Collection; import java.util.Objects; import java.util.function.Function; import java.util.stream.Stream; -import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; import org.opentripplanner.apis.gtfs.model.LocalDateRange; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.Trip; -import org.opentripplanner.transit.service.TransitService; /** * Encapsulates the logic to filter patterns by the service dates that they operate on. It also @@ -45,17 +43,6 @@ public PatternByServiceDatesFilter( } } - public PatternByServiceDatesFilter( - GraphQLTypes.GraphQLLocalDateRangeInput filterInput, - TransitService transitService - ) { - this( - new LocalDateRange(filterInput.getGraphQLStart(), filterInput.getGraphQLEnd()), - transitService::getPatternsForRoute, - trip -> transitService.getCalendarService().getServiceDatesForServiceId(trip.getServiceId()) - ); - } - /** * Filter the patterns by the service dates that it operates on. */ diff --git a/src/test/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilterTest.java b/src/test/java/org/opentripplanner/transit/service/PatternByServiceDatesFilterTest.java similarity index 92% rename from src/test/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilterTest.java rename to src/test/java/org/opentripplanner/transit/service/PatternByServiceDatesFilterTest.java index 934bc5a9b1e..55cb2ba9017 100644 --- a/src/test/java/org/opentripplanner/apis/gtfs/PatternByServiceDatesFilterTest.java +++ b/src/test/java/org/opentripplanner/transit/service/PatternByServiceDatesFilterTest.java @@ -1,18 +1,19 @@ -package org.opentripplanner.apis.gtfs; +package org.opentripplanner.transit.service; import static java.time.LocalDate.parse; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.opentripplanner.apis.gtfs.PatternByServiceDatesFilterTest.FilterExpectation.NOT_REMOVED; -import static org.opentripplanner.apis.gtfs.PatternByServiceDatesFilterTest.FilterExpectation.REMOVED; import static org.opentripplanner.apis.gtfs.PatternTestModel.ROUTE_1; +import static org.opentripplanner.transit.service.PatternByServiceDatesFilterTest.FilterExpectation.NOT_REMOVED; +import static org.opentripplanner.transit.service.PatternByServiceDatesFilterTest.FilterExpectation.REMOVED; import java.time.LocalDate; import java.util.List; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.opentripplanner.apis.gtfs.PatternTestModel; import org.opentripplanner.apis.gtfs.model.LocalDateRange; import org.opentripplanner.transit.model.network.TripPattern; From 0b5f0a84d4912cf6bef91cf54dedd366f69c1227 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 10 Sep 2024 16:47:18 +0200 Subject: [PATCH 24/47] Extract constant for TRIP1 --- .../siri/SiriTimetableSnapshotSourceTest.java | 43 +++++++++++-------- .../trip/RealtimeTestEnvironmentBuilder.java | 1 - 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java index e94ec1073a6..ff749f953cf 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java @@ -12,17 +12,22 @@ import org.opentripplanner.updater.trip.RealtimeTripInput; class SiriTimetableSnapshotSourceTest implements RealtimeTestConstants { + private static final RealtimeTripInput TRIP_1_INPUT = RealtimeTripInput + .of(TRIP_1_ID) + .addStop(STOP_A1, "0:00:10", "0:00:11") + .addStop(STOP_B1, "0:00:20", "0:00:21") + .build(); - private static final RealtimeTripInput TRIP2_INPUT = RealtimeTripInput + private static final RealtimeTripInput TRIP_2_INPUT = RealtimeTripInput .of(TRIP_2_ID) .addStop(STOP_A1, "0:01:00", "0:01:01") .addStop(STOP_B1, "0:01:10", "0:01:11") .addStop(STOP_C1, "0:01:20", "0:01:21") .build(); - + @Test void testCancelTrip() { - var env = RealtimeTestEnvironment.siri().withTrip1().build(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); assertEquals(RealTimeState.SCHEDULED, env.getTripTimesForTrip(TRIP_1_ID).getRealTimeState()); @@ -39,7 +44,7 @@ void testCancelTrip() { @Test void testAddJourney() { - var env = RealtimeTestEnvironment.siri().withTrip1().build(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withEstimatedVehicleJourneyCode("newJourney") @@ -62,7 +67,7 @@ void testAddJourney() { @Test void testAddedJourneyWithInvalidScheduledData() { - var env = RealtimeTestEnvironment.siri().withTrip1().build(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); // Create an extra journey with invalid planned data (travel back in time) // and valid real time data @@ -111,7 +116,7 @@ void testAddedJourneyWithUnresolvableAgency() { @Test void testReplaceJourney() { - var env = RealtimeTestEnvironment.siri().withTrip1().build(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withEstimatedVehicleJourneyCode("newJourney") @@ -144,7 +149,7 @@ void testReplaceJourney() { */ @Test void testUpdateJourneyWithDatedVehicleJourneyRef() { - var env = RealtimeTestEnvironment.siri().withTrip1().build(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = updatedJourneyBuilder(env) .withDatedVehicleJourneyRef(TRIP_1_ID) @@ -163,7 +168,7 @@ void testUpdateJourneyWithDatedVehicleJourneyRef() { */ @Test void testUpdateJourneyWithFramedVehicleJourneyRef() { - var env = RealtimeTestEnvironment.siri().withTrip1().build(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = updatedJourneyBuilder(env) .withFramedVehicleJourneyRef(builder -> @@ -180,7 +185,7 @@ void testUpdateJourneyWithFramedVehicleJourneyRef() { */ @Test void testUpdateJourneyWithoutJourneyRef() { - var env = RealtimeTestEnvironment.siri().withTrip1().build(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = updatedJourneyBuilder(env).buildEstimatedTimetableDeliveries(); var result = env.applyEstimatedTimetable(updates); @@ -193,7 +198,7 @@ void testUpdateJourneyWithoutJourneyRef() { */ @Test void testUpdateJourneyWithFuzzyMatching() { - var env = RealtimeTestEnvironment.siri().withTrip1().build(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = updatedJourneyBuilder(env).buildEstimatedTimetableDeliveries(); var result = env.applyEstimatedTimetableWithFuzzyMatcher(updates); @@ -207,7 +212,7 @@ void testUpdateJourneyWithFuzzyMatching() { */ @Test void testUpdateJourneyWithFuzzyMatchingAndMissingAimedDepartureTime() { - var env = RealtimeTestEnvironment.siri().withTrip1().build(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withFramedVehicleJourneyRef(builder -> @@ -232,7 +237,7 @@ void testUpdateJourneyWithFuzzyMatchingAndMissingAimedDepartureTime() { */ @Test void testChangeQuay() { - var env = RealtimeTestEnvironment.siri().withTrip1().build(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withDatedVehicleJourneyRef(TRIP_1_ID) @@ -253,7 +258,7 @@ void testChangeQuay() { @Test void testCancelStop() { - var env = RealtimeTestEnvironment.siri().addTrip(TRIP2_INPUT).build(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_2_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withDatedVehicleJourneyRef(TRIP_2_ID) @@ -281,7 +286,7 @@ void testCancelStop() { @Test @Disabled("Not supported yet") void testAddStop() { - var env = RealtimeTestEnvironment.siri().withTrip1().build(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withDatedVehicleJourneyRef(TRIP_1_ID) @@ -312,7 +317,7 @@ void testAddStop() { @Test void testNotMonitored() { - var env = RealtimeTestEnvironment.siri().withTrip1().build(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withMonitored(false) @@ -325,7 +330,7 @@ void testNotMonitored() { @Test void testReplaceJourneyWithoutEstimatedVehicleJourneyCode() { - var env = RealtimeTestEnvironment.siri().withTrip1().build(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withDatedVehicleJourneyRef("newJourney") @@ -350,7 +355,7 @@ void testReplaceJourneyWithoutEstimatedVehicleJourneyCode() { @Test void testNegativeHopTime() { - var env = RealtimeTestEnvironment.siri().withTrip1().build(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withDatedVehicleJourneyRef(TRIP_1_ID) @@ -370,7 +375,7 @@ void testNegativeHopTime() { @Test void testNegativeDwellTime() { - var env = RealtimeTestEnvironment.siri().addTrip(TRIP2_INPUT).build(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_2_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withDatedVehicleJourneyRef(TRIP_2_ID) @@ -395,7 +400,7 @@ void testNegativeDwellTime() { @Test @Disabled("Not supported yet") void testExtraUnknownStop() { - var env = RealtimeTestEnvironment.siri().withTrip1().build(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = new SiriEtBuilder(env.getDateTimeHelper()) .withDatedVehicleJourneyRef(TRIP_1_ID) diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java index 1887989bfbd..2783e3bc601 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java @@ -43,7 +43,6 @@ public RealtimeTestEnvironmentBuilder withTrip1() { public RealtimeTestEnvironmentBuilder addTrip(RealtimeTripInput trip) { createTrip(trip); - transitModel.index(); return this; } From 8a05a8daf448b9b6a48ea0a6082c766aaefd0004 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 10 Sep 2024 16:56:03 +0200 Subject: [PATCH 25/47] Replace withTrip1() with explicit setup --- .../ext/siri/SiriTimetableSnapshotSourceTest.java | 3 ++- .../updater/trip/RealtimeTestEnvironmentBuilder.java | 12 ------------ .../cancellation/CancellationDeletionTest.java | 12 +++++++++++- .../updater/trip/moduletests/delay/DelayedTest.java | 7 ++++++- .../trip/moduletests/rejection/InvalidInputTest.java | 8 +++++++- .../moduletests/rejection/InvalidTripIdTest.java | 2 +- 6 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java index ff749f953cf..e9ed1c47551 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java @@ -12,6 +12,7 @@ import org.opentripplanner.updater.trip.RealtimeTripInput; class SiriTimetableSnapshotSourceTest implements RealtimeTestConstants { + private static final RealtimeTripInput TRIP_1_INPUT = RealtimeTripInput .of(TRIP_1_ID) .addStop(STOP_A1, "0:00:10", "0:00:11") @@ -24,7 +25,7 @@ class SiriTimetableSnapshotSourceTest implements RealtimeTestConstants { .addStop(STOP_B1, "0:01:10", "0:01:11") .addStop(STOP_C1, "0:01:20", "0:01:21") .build(); - + @Test void testCancelTrip() { var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java index 2783e3bc601..a152b970f3c 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java @@ -29,18 +29,6 @@ RealtimeTestEnvironmentBuilder withSourceType(RealtimeTestEnvironment.SourceType return this; } - public RealtimeTestEnvironmentBuilder withTrip1() { - createTrip( - RealtimeTripInput - .of(TRIP_1_ID) - .addStop(STOP_A1, "0:00:10", "0:00:11") - .addStop(STOP_B1, "0:00:20", "0:00:21") - .build() - ); - transitModel.index(); - return this; - } - public RealtimeTestEnvironmentBuilder addTrip(RealtimeTripInput trip) { createTrip(trip); transitModel.index(); diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java index 775bdf4703a..d3ac5f3c89e 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java @@ -16,6 +16,7 @@ import org.opentripplanner.transit.model.timetable.RealTimeState; import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; +import org.opentripplanner.updater.trip.RealtimeTripInput; import org.opentripplanner.updater.trip.TripUpdateBuilder; /** @@ -34,7 +35,16 @@ static List cases() { @ParameterizedTest @MethodSource("cases") void cancelledTrip(ScheduleRelationship relationship, RealTimeState state) { - var env = RealtimeTestEnvironment.gtfs().withTrip1().build(); + var env = RealtimeTestEnvironment + .gtfs() + .addTrip( + RealtimeTripInput + .of(TRIP_1_ID) + .addStop(STOP_A1, "0:00:10", "0:00:11") + .addStop(STOP_B1, "0:00:20", "0:00:21") + .build() + ) + .build(); var pattern1 = env.getPatternForTrip(TRIP_1_ID); final int tripIndex1 = pattern1.getScheduledTimetable().getTripIndex(id(TRIP_1_ID)); diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java index 49fb792451d..c5c86f36707 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java @@ -25,7 +25,12 @@ class DelayedTest implements RealtimeTestConstants { @Test void singleStopDelay() { - var env = RealtimeTestEnvironment.gtfs().withTrip1().build(); + var TRIP_INPUT = RealtimeTripInput + .of(TRIP_1_ID) + .addStop(STOP_A1, "0:00:10", "0:00:11") + .addStop(STOP_B1, "0:00:20", "0:00:21") + .build(); + var env = RealtimeTestEnvironment.gtfs().addTrip(TRIP_INPUT).build(); var tripUpdate = new TripUpdateBuilder(TRIP_1_ID, SERVICE_DATE, SCHEDULED, TIME_ZONE) .addDelayedStopTime(STOP_SEQUENCE, DELAY) diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java index 2e04c16aba1..3314e7b63bb 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java @@ -11,6 +11,7 @@ import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; +import org.opentripplanner.updater.trip.RealtimeTripInput; import org.opentripplanner.updater.trip.TripUpdateBuilder; /** @@ -26,7 +27,12 @@ public static List cases() { @ParameterizedTest @MethodSource("cases") void invalidTripDate(LocalDate date) { - var env = RealtimeTestEnvironment.gtfs().withTrip1().build(); + var tripInput = RealtimeTripInput + .of(TRIP_1_ID) + .addStop(STOP_A1, "0:00:10", "0:00:11") + .addStop(STOP_B1, "0:00:20", "0:00:21") + .build(); + var env = RealtimeTestEnvironment.gtfs().addTrip(tripInput).build(); var update = new TripUpdateBuilder(TRIP_1_ID, date, SCHEDULED, TIME_ZONE) .addDelayedStopTime(2, 60, 80) diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidTripIdTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidTripIdTest.java index bb723d4acab..699e8fe865c 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidTripIdTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidTripIdTest.java @@ -22,7 +22,7 @@ static Stream invalidCases() { @ParameterizedTest(name = "tripId=\"{0}\"") @MethodSource("invalidCases") void invalidTripId(String tripId) { - var env = RealtimeTestEnvironment.gtfs().withTrip1().build(); + var env = RealtimeTestEnvironment.gtfs().build(); var tripDescriptorBuilder = GtfsRealtime.TripDescriptor.newBuilder(); if (tripId != null) { tripDescriptorBuilder.setTripId(tripId); From 05764bfefcce7d3f8f9639486fff7ee552fce872 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 10 Sep 2024 17:12:31 +0200 Subject: [PATCH 26/47] Move StopCall into class --- .../updater/trip/RealtimeTestEnvironmentBuilder.java | 4 +++- .../org/opentripplanner/updater/trip/RealtimeTripInput.java | 2 ++ src/test/java/org/opentripplanner/updater/trip/StopCall.java | 5 ----- 3 files changed, 5 insertions(+), 6 deletions(-) delete mode 100644 src/test/java/org/opentripplanner/updater/trip/StopCall.java diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java index a152b970f3c..2ef9a9ee483 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java @@ -80,7 +80,9 @@ private Trip createTrip(RealtimeTripInput tripInput) { final TripPattern pattern = TransitModelForTest .tripPattern(tripInput.id() + "Pattern", tripInput.route()) .withStopPattern( - TransitModelForTest.stopPattern(tripInput.stops().stream().map(StopCall::stop).toList()) + TransitModelForTest.stopPattern( + tripInput.stops().stream().map(RealtimeTripInput.StopCall::stop).toList() + ) ) .build(); pattern.add(tripTimes); diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java index 51af39aafcd..73c0e87e0f6 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java @@ -37,4 +37,6 @@ public RealtimeTripInput build() { return new RealtimeTripInput(id, route, stops); } } + + static record StopCall(RegularStop stop, int arrivalTime, int departureTime) {} } diff --git a/src/test/java/org/opentripplanner/updater/trip/StopCall.java b/src/test/java/org/opentripplanner/updater/trip/StopCall.java deleted file mode 100644 index 164b2420c87..00000000000 --- a/src/test/java/org/opentripplanner/updater/trip/StopCall.java +++ /dev/null @@ -1,5 +0,0 @@ -package org.opentripplanner.updater.trip; - -import org.opentripplanner.transit.model.site.RegularStop; - -record StopCall(RegularStop stop, int arrivalTime, int departureTime) {} From 13f7287898fb8bcfc5d7e0c5bacae855e7cd706d Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 10 Sep 2024 21:41:13 +0200 Subject: [PATCH 27/47] Fix code after merge --- .../ext/siri/SiriTimetableSnapshotSourceTest.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java index 7ba46984c6f..96139c20058 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java @@ -10,6 +10,7 @@ import org.opentripplanner.updater.spi.UpdateError; import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; +import org.opentripplanner.updater.trip.RealtimeTripInput; import uk.org.siri.siri20.EstimatedTimetableDeliveryStructure; class SiriTimetableSnapshotSourceTest implements RealtimeTestConstants { @@ -45,7 +46,7 @@ void testCancelTrip() { @Test void testAddJourney() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().build(); var updates = createValidAddedJourney(env); var result = env.applyEstimatedTimetable(updates); @@ -59,7 +60,7 @@ void testAddJourney() { @Test void testAddJourneyMultipleTimes() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().build(); var updates = createValidAddedJourney(env); int numTrips = env.getTransitService().getAllTrips().size(); @@ -434,10 +435,10 @@ private static List createValidAddedJourney return new SiriEtBuilder(env.getDateTimeHelper()) .withEstimatedVehicleJourneyCode("newJourney") .withIsExtraJourney(true) - .withOperatorRef(env.operator1Id.getId()) - .withLineRef(env.route1Id.getId()) - .withRecordedCalls(builder -> builder.call(env.stopC1).departAimedActual("00:01", "00:02")) - .withEstimatedCalls(builder -> builder.call(env.stopD1).arriveAimedExpected("00:03", "00:04")) + .withOperatorRef(OPERATOR_1_ID) + .withLineRef(ROUTE_1_ID) + .withRecordedCalls(builder -> builder.call(STOP_C1).departAimedActual("00:01", "00:02")) + .withEstimatedCalls(builder -> builder.call(STOP_D1).arriveAimedExpected("00:03", "00:04")) .buildEstimatedTimetableDeliveries(); } From 4633563ac5176e53f8337113b846f22b3f20f2dc Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 10 Sep 2024 21:57:57 +0200 Subject: [PATCH 28/47] Fix new test cases --- .../ext/siri/SiriTimetableSnapshotSourceTest.java | 8 ++++++-- .../opentripplanner/updater/trip/RealtimeTripInput.java | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java index 96139c20058..597b54f76b3 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java @@ -14,6 +14,7 @@ import uk.org.siri.siri20.EstimatedTimetableDeliveryStructure; class SiriTimetableSnapshotSourceTest implements RealtimeTestConstants { + private static final RealtimeTripInput TRIP_1_INPUT = RealtimeTripInput .of(TRIP_1_ID) .addStop(STOP_A1, "0:00:10", "0:00:11") @@ -46,7 +47,8 @@ void testCancelTrip() { @Test void testAddJourney() { - var env = RealtimeTestEnvironment.siri().build(); + // we actually don't need the trip, but it's the only way to add a route to the index + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = createValidAddedJourney(env); var result = env.applyEstimatedTimetable(updates); @@ -60,7 +62,8 @@ void testAddJourney() { @Test void testAddJourneyMultipleTimes() { - var env = RealtimeTestEnvironment.siri().build(); + // we actually don't need the trip, but it's the only way to add a route to the index + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); var updates = createValidAddedJourney(env); int numTrips = env.getTransitService().getAllTrips().size(); @@ -74,6 +77,7 @@ void testAddJourneyMultipleTimes() { @Test void testAddedJourneyWithInvalidScheduledData() { + // we actually don't need the trip, but it's the only way to add a route to the index var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); // Create an extra journey with invalid planned data (travel back in time) diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java index 73c0e87e0f6..f3077460856 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java @@ -38,5 +38,5 @@ public RealtimeTripInput build() { } } - static record StopCall(RegularStop stop, int arrivalTime, int departureTime) {} + record StopCall(RegularStop stop, int arrivalTime, int departureTime) {} } From 5e42b34839d92ad9b3490b5d28a58e5e1a2055db Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 11 Sep 2024 09:41:56 +0200 Subject: [PATCH 29/47] Rename RealtimeTripInput to TripInput --- .../siri/SiriTimetableSnapshotSourceTest.java | 6 ++--- .../trip/RealtimeTestEnvironmentBuilder.java | 6 ++--- ...{RealtimeTripInput.java => TripInput.java} | 24 +++++++++---------- .../CancellationDeletionTest.java | 4 ++-- .../trip/moduletests/delay/DelayedTest.java | 6 ++--- .../trip/moduletests/delay/SkippedTest.java | 4 ++-- .../rejection/InvalidInputTest.java | 4 ++-- 7 files changed, 27 insertions(+), 27 deletions(-) rename src/test/java/org/opentripplanner/updater/trip/{RealtimeTripInput.java => TripInput.java} (55%) diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java index 597b54f76b3..24b292a51bd 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java @@ -10,18 +10,18 @@ import org.opentripplanner.updater.spi.UpdateError; import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; -import org.opentripplanner.updater.trip.RealtimeTripInput; +import org.opentripplanner.updater.trip.TripInput; import uk.org.siri.siri20.EstimatedTimetableDeliveryStructure; class SiriTimetableSnapshotSourceTest implements RealtimeTestConstants { - private static final RealtimeTripInput TRIP_1_INPUT = RealtimeTripInput + private static final TripInput TRIP_1_INPUT = TripInput .of(TRIP_1_ID) .addStop(STOP_A1, "0:00:10", "0:00:11") .addStop(STOP_B1, "0:00:20", "0:00:21") .build(); - private static final RealtimeTripInput TRIP_2_INPUT = RealtimeTripInput + private static final TripInput TRIP_2_INPUT = TripInput .of(TRIP_2_ID) .addStop(STOP_A1, "0:01:00", "0:01:01") .addStop(STOP_B1, "0:01:10", "0:01:11") diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java index 2ef9a9ee483..7bca71736be 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java @@ -29,7 +29,7 @@ RealtimeTestEnvironmentBuilder withSourceType(RealtimeTestEnvironment.SourceType return this; } - public RealtimeTestEnvironmentBuilder addTrip(RealtimeTripInput trip) { + public RealtimeTestEnvironmentBuilder addTrip(TripInput trip) { createTrip(trip); transitModel.index(); return this; @@ -51,7 +51,7 @@ public RealtimeTestEnvironment build() { return new RealtimeTestEnvironment(sourceType, transitModel); } - private Trip createTrip(RealtimeTripInput tripInput) { + private Trip createTrip(TripInput tripInput) { var trip = Trip .of(id(tripInput.id())) .withRoute(tripInput.route()) @@ -81,7 +81,7 @@ private Trip createTrip(RealtimeTripInput tripInput) { .tripPattern(tripInput.id() + "Pattern", tripInput.route()) .withStopPattern( TransitModelForTest.stopPattern( - tripInput.stops().stream().map(RealtimeTripInput.StopCall::stop).toList() + tripInput.stops().stream().map(TripInput.StopCall::stop).toList() ) ) .build(); diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java b/src/test/java/org/opentripplanner/updater/trip/TripInput.java similarity index 55% rename from src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java rename to src/test/java/org/opentripplanner/updater/trip/TripInput.java index f3077460856..c7746b3b3f8 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTripInput.java +++ b/src/test/java/org/opentripplanner/updater/trip/TripInput.java @@ -6,35 +6,35 @@ import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.site.RegularStop; -public record RealtimeTripInput(String id, Route route, List stops) { - public static RealtimeTripInputBuilder of(String id) { - return new RealtimeTripInputBuilder(id); +/** + * A simple data structure that is used by the {@link RealtimeTestEnvironment} to create + * trips, trips on date and patterns. + */ +public record TripInput(String id, Route route, List stops) { + public static TripInputBuilder of(String id) { + return new TripInputBuilder(id); } - public static class RealtimeTripInputBuilder implements RealtimeTestConstants { + public static class TripInputBuilder implements RealtimeTestConstants { private final String id; private final List stops = new ArrayList<>(); // can be made configurable if needed private final Route route = ROUTE_1; - RealtimeTripInputBuilder(String id) { + TripInputBuilder(String id) { this.id = id; } - public RealtimeTripInputBuilder addStop( - RegularStop stopId, - String arrivalTime, - String departureTime - ) { + public TripInputBuilder addStop(RegularStop stopId, String arrivalTime, String departureTime) { this.stops.add( new StopCall(stopId, TimeUtils.time(arrivalTime), TimeUtils.time(departureTime)) ); return this; } - public RealtimeTripInput build() { - return new RealtimeTripInput(id, route, stops); + public TripInput build() { + return new TripInput(id, route, stops); } } diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java index d3ac5f3c89e..b8bd5c4574b 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/cancellation/CancellationDeletionTest.java @@ -16,7 +16,7 @@ import org.opentripplanner.transit.model.timetable.RealTimeState; import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; -import org.opentripplanner.updater.trip.RealtimeTripInput; +import org.opentripplanner.updater.trip.TripInput; import org.opentripplanner.updater.trip.TripUpdateBuilder; /** @@ -38,7 +38,7 @@ void cancelledTrip(ScheduleRelationship relationship, RealTimeState state) { var env = RealtimeTestEnvironment .gtfs() .addTrip( - RealtimeTripInput + TripInput .of(TRIP_1_ID) .addStop(STOP_A1, "0:00:10", "0:00:11") .addStop(STOP_B1, "0:00:20", "0:00:21") diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java index c5c86f36707..f45a82b9ba0 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/DelayedTest.java @@ -12,7 +12,7 @@ import org.opentripplanner.transit.model.timetable.RealTimeState; import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; -import org.opentripplanner.updater.trip.RealtimeTripInput; +import org.opentripplanner.updater.trip.TripInput; import org.opentripplanner.updater.trip.TripUpdateBuilder; /** @@ -25,7 +25,7 @@ class DelayedTest implements RealtimeTestConstants { @Test void singleStopDelay() { - var TRIP_INPUT = RealtimeTripInput + var TRIP_INPUT = TripInput .of(TRIP_1_ID) .addStop(STOP_A1, "0:00:10", "0:00:11") .addStop(STOP_B1, "0:00:20", "0:00:21") @@ -72,7 +72,7 @@ void singleStopDelay() { */ @Test void complexDelay() { - var tripInput = RealtimeTripInput + var tripInput = TripInput .of(TRIP_2_ID) .addStop(STOP_A1, "0:01:00", "0:01:01") .addStop(STOP_B1, "0:01:10", "0:01:11") diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java index 16e201ed515..f9799ba6512 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/delay/SkippedTest.java @@ -15,7 +15,7 @@ import org.opentripplanner.transit.model.timetable.TripTimesStringBuilder; import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; -import org.opentripplanner.updater.trip.RealtimeTripInput; +import org.opentripplanner.updater.trip.TripInput; import org.opentripplanner.updater.trip.TripUpdateBuilder; /** @@ -23,7 +23,7 @@ */ class SkippedTest implements RealtimeTestConstants { - private static final RealtimeTripInput TRIP_INPUT = RealtimeTripInput + private static final TripInput TRIP_INPUT = TripInput .of(TRIP_2_ID) .addStop(STOP_A1, "0:01:00", "0:01:01") .addStop(STOP_B1, "0:01:10", "0:01:11") diff --git a/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java b/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java index 3314e7b63bb..2ba6749b4b0 100644 --- a/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java +++ b/src/test/java/org/opentripplanner/updater/trip/moduletests/rejection/InvalidInputTest.java @@ -11,7 +11,7 @@ import org.junit.jupiter.params.provider.MethodSource; import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; -import org.opentripplanner.updater.trip.RealtimeTripInput; +import org.opentripplanner.updater.trip.TripInput; import org.opentripplanner.updater.trip.TripUpdateBuilder; /** @@ -27,7 +27,7 @@ public static List cases() { @ParameterizedTest @MethodSource("cases") void invalidTripDate(LocalDate date) { - var tripInput = RealtimeTripInput + var tripInput = TripInput .of(TRIP_1_ID) .addStop(STOP_A1, "0:00:10", "0:00:11") .addStop(STOP_B1, "0:00:20", "0:00:21") From 88ec5638c8c0e9ec4c1f83a0231754daa09eeadb Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 11 Sep 2024 16:15:17 +0200 Subject: [PATCH 30/47] Adapt tests to new realtime code --- .../siri/SiriTimetableSnapshotSourceTest.java | 16 +++++++--------- .../updater/trip/RealtimeTestConstants.java | 4 ++++ .../updater/trip/RealtimeTestEnvironment.java | 10 ++++------ .../opentripplanner/updater/trip/TripInput.java | 7 ++++++- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java index d782397b65a..d10dbc05090 100644 --- a/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/siri/SiriTimetableSnapshotSourceTest.java @@ -2,12 +2,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.opentripplanner.transit.model._data.TransitModelForTest.id; import static org.opentripplanner.updater.spi.UpdateResultAssertions.assertFailure; -import static org.opentripplanner.updater.trip.RealtimeTestEnvironment.SERVICE_DATE; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import org.opentripplanner.transit.model._data.TransitModelForTest; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.timetable.RealTimeState; @@ -18,12 +17,12 @@ import org.opentripplanner.updater.trip.RealtimeTestConstants; import org.opentripplanner.updater.trip.RealtimeTestEnvironment; import org.opentripplanner.updater.trip.TripInput; -import uk.org.siri.siri20.EstimatedTimetableDeliveryStructure; class SiriTimetableSnapshotSourceTest implements RealtimeTestConstants { private static final TripInput TRIP_1_INPUT = TripInput .of(TRIP_1_ID) + .withRoute(ROUTE_1.copy().withOperator(OPERATOR1).build()) .addStop(STOP_A1, "0:00:10", "0:00:11") .addStop(STOP_B1, "0:00:20", "0:00:21") .build(); @@ -54,9 +53,9 @@ void testCancelTrip() { @Test void testAddJourneyWithExistingRoute() { - var env = RealtimeTestEnvironment.siri(); + var env = RealtimeTestEnvironment.siri().addTrip(TRIP_1_INPUT).build(); - Route route = env.getTransitService().getRouteForId(env.route1Id); + Route route = ROUTE_1; int numPatternForRoute = env.getTransitService().getPatternsForRoute(route).size(); String newJourneyId = "newJourney"; @@ -70,7 +69,7 @@ void testAddJourneyWithExistingRoute() { "SCHEDULED | C1 0:01 0:01 | D1 0:03 0:03", env.getScheduledTimetable(newJourneyId) ); - FeedScopedId tripId = TransitModelForTest.id(newJourneyId); + FeedScopedId tripId = id(newJourneyId); TransitService transitService = env.getTransitService(); Trip trip = transitService.getTripForId(tripId); assertNotNull(trip); @@ -109,7 +108,7 @@ void testAddJourneyWithNewRoute() { ); TransitService transitService = env.getTransitService(); assertEquals(numRoutes + 1, transitService.getAllRoutes().size()); - FeedScopedId newRouteId = TransitModelForTest.id(newRouteRef); + FeedScopedId newRouteId = id(newRouteRef); Route newRoute = transitService.getRouteForId(newRouteId); assertNotNull(newRoute); assertEquals(1, transitService.getPatternsForRoute(newRoute).size()); @@ -495,8 +494,7 @@ private static SiriEtBuilder createValidAddedJourney(RealtimeTestEnvironment env .withOperatorRef(OPERATOR_1_ID) .withLineRef(ROUTE_1_ID) .withRecordedCalls(builder -> builder.call(STOP_C1).departAimedActual("00:01", "00:02")) - .withEstimatedCalls(builder -> builder.call(STOP_D1).arriveAimedExpected("00:03", "00:04") - ); + .withEstimatedCalls(builder -> builder.call(STOP_D1).arriveAimedExpected("00:03", "00:04")); } private static SiriEtBuilder updatedJourneyBuilder(RealtimeTestEnvironment env) { diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestConstants.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestConstants.java index 81e3759585b..bad0c1982e9 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestConstants.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestConstants.java @@ -1,10 +1,13 @@ package org.opentripplanner.updater.trip; +import static org.opentripplanner.transit.model._data.TransitModelForTest.id; + import java.time.LocalDate; import java.time.ZoneId; import org.opentripplanner.transit.model._data.TransitModelForTest; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.Route; +import org.opentripplanner.transit.model.organization.Operator; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.Station; import org.opentripplanner.transit.service.StopModel; @@ -18,6 +21,7 @@ public interface RealtimeTestConstants { String TRIP_1_ID = "TestTrip1"; String TRIP_2_ID = "TestTrip2"; String OPERATOR_1_ID = "TestOperator1"; + Operator OPERATOR1 = Operator.of(id(OPERATOR_1_ID)).withName(OPERATOR_1_ID).build(); String ROUTE_1_ID = "TestRoute1"; TransitModelForTest TEST_MODEL = TransitModelForTest.of(); diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java index 50c91a0c694..e44c07039f9 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java @@ -18,11 +18,6 @@ import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.organization.Operator; -import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.model.site.Station; -import org.opentripplanner.transit.model.site.StopLocation; -import org.opentripplanner.transit.model.timetable.Trip; -import org.opentripplanner.transit.model.timetable.TripOnServiceDate; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.model.timetable.TripTimesStringBuilder; import org.opentripplanner.transit.service.DefaultTransitService; @@ -75,7 +70,10 @@ public static RealtimeTestEnvironmentBuilder gtfs() { RealtimeTestEnvironment(SourceType sourceType, TransitModel transitModel) { Objects.requireNonNull(sourceType); this.transitModel = transitModel; - operator1 = Operator.of(operator1Id).withName("Operator 1").build(); + var operator1 = Operator + .of(id(OPERATOR_1_ID)) + .withName("Name of %s".formatted(OPERATOR_1_ID)) + .build(); transitModel.getOperators().add(operator1); this.transitModel.index(); diff --git a/src/test/java/org/opentripplanner/updater/trip/TripInput.java b/src/test/java/org/opentripplanner/updater/trip/TripInput.java index c7746b3b3f8..e4d9309061a 100644 --- a/src/test/java/org/opentripplanner/updater/trip/TripInput.java +++ b/src/test/java/org/opentripplanner/updater/trip/TripInput.java @@ -20,7 +20,7 @@ public static class TripInputBuilder implements RealtimeTestConstants { private final String id; private final List stops = new ArrayList<>(); // can be made configurable if needed - private final Route route = ROUTE_1; + private Route route = ROUTE_1; TripInputBuilder(String id) { this.id = id; @@ -36,6 +36,11 @@ public TripInputBuilder addStop(RegularStop stopId, String arrivalTime, String d public TripInput build() { return new TripInput(id, route, stops); } + + public TripInputBuilder withRoute(Route route) { + this.route = route; + return this; + } } record StopCall(RegularStop stop, int arrivalTime, int departureTime) {} From b479e201a2036b909d55f9506076a1f287c50eda Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 11 Sep 2024 16:22:28 +0200 Subject: [PATCH 31/47] Add operator in builder --- .../updater/trip/RealtimeTestEnvironment.java | 6 ------ .../updater/trip/RealtimeTestEnvironmentBuilder.java | 4 ++++ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java index e44c07039f9..682bff038b6 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironment.java @@ -17,7 +17,6 @@ import org.opentripplanner.transit.model._data.TransitModelForTest; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.TripPattern; -import org.opentripplanner.transit.model.organization.Operator; import org.opentripplanner.transit.model.timetable.TripTimes; import org.opentripplanner.transit.model.timetable.TripTimesStringBuilder; import org.opentripplanner.transit.service.DefaultTransitService; @@ -70,11 +69,6 @@ public static RealtimeTestEnvironmentBuilder gtfs() { RealtimeTestEnvironment(SourceType sourceType, TransitModel transitModel) { Objects.requireNonNull(sourceType); this.transitModel = transitModel; - var operator1 = Operator - .of(id(OPERATOR_1_ID)) - .withName("Name of %s".formatted(OPERATOR_1_ID)) - .build(); - transitModel.getOperators().add(operator1); this.transitModel.index(); // SIRI and GTFS-RT cannot be registered with the transit model at the same time diff --git a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java index 7bca71736be..7a79b27923e 100644 --- a/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java +++ b/src/test/java/org/opentripplanner/updater/trip/RealtimeTestEnvironmentBuilder.java @@ -67,6 +67,10 @@ private Trip createTrip(TripInput tripInput) { transitModel.addTripOnServiceDate(tripOnServiceDate.getId(), tripOnServiceDate); + if (tripInput.route().getOperator() != null) { + transitModel.getOperators().add(tripInput.route().getOperator()); + } + var stopTimes = IntStream .range(0, tripInput.stops().size()) .mapToObj(i -> { From a6182194d3f17feced1cb6b2e40c50cc6c68ca8c Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 16 Sep 2024 10:17:42 +0200 Subject: [PATCH 32/47] Move LayerFilters up one level --- .../ext/vectortiles/layers/{stops => }/LayerFiltersTest.java | 2 +- .../ext/vectortiles/layers/{stops => }/LayerFilters.java | 2 +- .../ext/vectortiles/layers/stops/StopsLayerBuilder.java | 1 + .../org/opentripplanner/inspector/vector/LayerParameters.java | 2 +- .../standalone/config/routerconfig/VectorTileConfig.java | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) rename src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/{stops => }/LayerFiltersTest.java (95%) rename src/ext/java/org/opentripplanner/ext/vectortiles/layers/{stops => }/LayerFilters.java (97%) diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFiltersTest.java b/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/LayerFiltersTest.java similarity index 95% rename from src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFiltersTest.java rename to src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/LayerFiltersTest.java index 6021662ab4b..e0418ac0c57 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFiltersTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/LayerFiltersTest.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.vectortiles.layers.stops; +package org.opentripplanner.ext.vectortiles.layers; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFilters.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/LayerFilters.java similarity index 97% rename from src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFilters.java rename to src/ext/java/org/opentripplanner/ext/vectortiles/layers/LayerFilters.java index 54e4052ee63..bdd83a2c020 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/LayerFilters.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/LayerFilters.java @@ -1,4 +1,4 @@ -package org.opentripplanner.ext.vectortiles.layers.stops; +package org.opentripplanner.ext.vectortiles.layers; import java.time.DayOfWeek; import java.time.LocalDate; diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java index 94497f83d0d..141157f8f3e 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/stops/StopsLayerBuilder.java @@ -9,6 +9,7 @@ import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.opentripplanner.ext.vectortiles.VectorTilesResource; +import org.opentripplanner.ext.vectortiles.layers.LayerFilters; import org.opentripplanner.inspector.vector.LayerBuilder; import org.opentripplanner.inspector.vector.LayerParameters; import org.opentripplanner.transit.model.site.RegularStop; diff --git a/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java b/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java index c4e64f39ab8..70cb5a2ce43 100644 --- a/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java +++ b/src/main/java/org/opentripplanner/inspector/vector/LayerParameters.java @@ -1,7 +1,7 @@ package org.opentripplanner.inspector.vector; import org.opentripplanner.apis.support.mapping.PropertyMapper; -import org.opentripplanner.ext.vectortiles.layers.stops.LayerFilters; +import org.opentripplanner.ext.vectortiles.layers.LayerFilters; /** * Configuration options for a single vector tile layer. diff --git a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java index 1eb75c8d394..26d56dc0dba 100644 --- a/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/routerconfig/VectorTileConfig.java @@ -14,7 +14,7 @@ import javax.annotation.Nullable; import org.opentripplanner.ext.vectortiles.VectorTilesResource; import org.opentripplanner.ext.vectortiles.VectorTilesResource.LayerType; -import org.opentripplanner.ext.vectortiles.layers.stops.LayerFilters; +import org.opentripplanner.ext.vectortiles.layers.LayerFilters; import org.opentripplanner.inspector.vector.LayerParameters; import org.opentripplanner.standalone.config.framework.json.NodeAdapter; From 5c76b0b7bae0da6562123194a59bc63d2314d4ef Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 16 Sep 2024 10:21:22 +0200 Subject: [PATCH 33/47] Rename variable --- .../ext/vectortiles/layers/LayerFiltersTest.java | 4 ++-- .../ext/vectortiles/layers/LayerFilters.java | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/LayerFiltersTest.java b/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/LayerFiltersTest.java index e0418ac0c57..a3c18366d3d 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/LayerFiltersTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/LayerFiltersTest.java @@ -19,7 +19,7 @@ class LayerFiltersTest { @Test void includeStopWithinServiceWeek() { - var predicate = LayerFilters.currentServiceWeek( + var predicate = LayerFilters.buildCurrentServiceWeekPredicate( s -> List.of(PATTERN), trip -> List.of(DATE), () -> DATE @@ -31,7 +31,7 @@ void includeStopWithinServiceWeek() { @Test void excludeOutsideServiceWeek() { var inThreeWeeks = DATE.plusDays(21); - var predicate = LayerFilters.currentServiceWeek( + var predicate = LayerFilters.buildCurrentServiceWeekPredicate( s -> List.of(PATTERN), trip -> List.of(inThreeWeeks), () -> DATE diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/LayerFilters.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/LayerFilters.java index bdd83a2c020..7b8d939e38c 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/LayerFilters.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/LayerFilters.java @@ -30,17 +30,18 @@ public class LayerFilters { * Returns a predicate which only includes stop which are visited by a pattern that is in the current * TriMet service week, namely from Sunday to Sunday. */ - public static Predicate currentServiceWeek( + public static Predicate buildCurrentServiceWeekPredicate( Function> getPatternsForStop, Function> getServiceDatesForTrip, Supplier nowSupplier ) { var serviceDate = nowSupplier.get(); var lastSunday = serviceDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY)); - var nextSunday = serviceDate.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)).plusDays(1); + var nextSundayPlusOne = serviceDate.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)).plusDays(1); var filter = new PatternByServiceDatesFilter( - new LocalDateRange(lastSunday, nextSunday), + // reminder, the end of the date range is exclusive so it's the next Sunday plus one day + new LocalDateRange(lastSunday, nextSundayPlusOne), // not used route -> List.of(), getServiceDatesForTrip @@ -56,7 +57,7 @@ public static Predicate currentServiceWeek( public static Predicate forType(FilterType type, TransitService transitService) { return switch (type) { case NONE -> NO_FILTER; - case CURRENT_TRIMET_SERVICE_WEEK -> currentServiceWeek( + case CURRENT_TRIMET_SERVICE_WEEK -> buildCurrentServiceWeekPredicate( transitService::getPatternsForStop, trip -> transitService.getCalendarService().getServiceDatesForServiceId(trip.getServiceId()), From cc51cb1fa0555379accd751a09dcee9024dda20b Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 16 Sep 2024 10:35:32 +0200 Subject: [PATCH 34/47] Move test generation model --- .../ext/vectortiles/layers/LayerFiltersTest.java | 2 +- .../gtfs => transit/model/_data}/PatternTestModel.java | 6 ++++-- .../transit/service/PatternByServiceDatesFilterTest.java | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) rename src/test/java/org/opentripplanner/{apis/gtfs => transit/model/_data}/PatternTestModel.java (90%) diff --git a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/LayerFiltersTest.java b/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/LayerFiltersTest.java index a3c18366d3d..f12d43b62cf 100644 --- a/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/LayerFiltersTest.java +++ b/src/ext-test/java/org/opentripplanner/ext/vectortiles/layers/LayerFiltersTest.java @@ -6,7 +6,7 @@ import java.time.LocalDate; import java.util.List; import org.junit.jupiter.api.Test; -import org.opentripplanner.apis.gtfs.PatternTestModel; +import org.opentripplanner.transit.model._data.PatternTestModel; import org.opentripplanner.transit.model._data.TransitModelForTest; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.site.RegularStop; diff --git a/src/test/java/org/opentripplanner/apis/gtfs/PatternTestModel.java b/src/test/java/org/opentripplanner/transit/model/_data/PatternTestModel.java similarity index 90% rename from src/test/java/org/opentripplanner/apis/gtfs/PatternTestModel.java rename to src/test/java/org/opentripplanner/transit/model/_data/PatternTestModel.java index fda75d9e174..c3afd0ddf61 100644 --- a/src/test/java/org/opentripplanner/apis/gtfs/PatternTestModel.java +++ b/src/test/java/org/opentripplanner/transit/model/_data/PatternTestModel.java @@ -1,8 +1,7 @@ -package org.opentripplanner.apis.gtfs; +package org.opentripplanner.transit.model._data; import static org.opentripplanner.transit.model._data.TransitModelForTest.id; -import org.opentripplanner.transit.model._data.TransitModelForTest; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.StopPattern; @@ -26,6 +25,9 @@ public class PatternTestModel { private static final RegularStop STOP_1 = MODEL.stop("1").build(); private static final StopPattern STOP_PATTERN = TransitModelForTest.stopPattern(STOP_1, STOP_1); + /** + * Creates a trip pattern that has a stop pattern, trip times and a trip with a service id. + */ public static TripPattern pattern() { var pattern = TransitModelForTest .tripPattern("1", ROUTE_1) diff --git a/src/test/java/org/opentripplanner/transit/service/PatternByServiceDatesFilterTest.java b/src/test/java/org/opentripplanner/transit/service/PatternByServiceDatesFilterTest.java index 55cb2ba9017..ffc734f6038 100644 --- a/src/test/java/org/opentripplanner/transit/service/PatternByServiceDatesFilterTest.java +++ b/src/test/java/org/opentripplanner/transit/service/PatternByServiceDatesFilterTest.java @@ -4,7 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.opentripplanner.apis.gtfs.PatternTestModel.ROUTE_1; +import static org.opentripplanner.transit.model._data.PatternTestModel.ROUTE_1; import static org.opentripplanner.transit.service.PatternByServiceDatesFilterTest.FilterExpectation.NOT_REMOVED; import static org.opentripplanner.transit.service.PatternByServiceDatesFilterTest.FilterExpectation.REMOVED; @@ -13,8 +13,8 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.opentripplanner.apis.gtfs.PatternTestModel; import org.opentripplanner.apis.gtfs.model.LocalDateRange; +import org.opentripplanner.transit.model._data.PatternTestModel; import org.opentripplanner.transit.model.network.TripPattern; class PatternByServiceDatesFilterTest { From 8b885dc60079ab157cec2d45434a0d8ca31a9776 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 16 Sep 2024 12:17:49 +0200 Subject: [PATCH 35/47] Rename enum to SUNDAY_TO_SUNDAY_SERVICE_WEEK --- doc/user/examples/ibi/portland/router-config.json | 2 +- doc/user/sandbox/MapboxVectorTilesApi.md | 2 +- .../opentripplanner/ext/vectortiles/layers/LayerFilters.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/user/examples/ibi/portland/router-config.json b/doc/user/examples/ibi/portland/router-config.json index 8e392152dca..acbcbc2e0a0 100644 --- a/doc/user/examples/ibi/portland/router-config.json +++ b/doc/user/examples/ibi/portland/router-config.json @@ -70,7 +70,7 @@ "maxZoom": 20, "minZoom": 14, "cacheMaxSeconds": 600, - "filter": "current-trimet-service-week" + "filter": "sunday-to-sunday-service-week" }, { "name": "areaStops", diff --git a/doc/user/sandbox/MapboxVectorTilesApi.md b/doc/user/sandbox/MapboxVectorTilesApi.md index 9720f4e95f9..4430a398a5d 100644 --- a/doc/user/sandbox/MapboxVectorTilesApi.md +++ b/doc/user/sandbox/MapboxVectorTilesApi.md @@ -250,7 +250,7 @@ The value is a fraction of the tile size. If you are having problem with icons a **Since version:** `2.6` ∙ **Type:** `enum` ∙ **Cardinality:** `Optional` ∙ **Default value:** `"none"` **Path:** /vectorTiles/layers/[0] -**Enum values:** `none` | `current-trimet-service-week` +**Enum values:** `none` | `sunday-to-sunday-service-week` Reduce the result set of a layer further by a specific filter. diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/LayerFilters.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/LayerFilters.java index 7b8d939e38c..9672a9810c1 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/LayerFilters.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/LayerFilters.java @@ -57,7 +57,7 @@ public static Predicate buildCurrentServiceWeekPredicate( public static Predicate forType(FilterType type, TransitService transitService) { return switch (type) { case NONE -> NO_FILTER; - case CURRENT_TRIMET_SERVICE_WEEK -> buildCurrentServiceWeekPredicate( + case SUNDAY_TO_SUNDAY_SERVICE_WEEK -> buildCurrentServiceWeekPredicate( transitService::getPatternsForStop, trip -> transitService.getCalendarService().getServiceDatesForServiceId(trip.getServiceId()), @@ -68,6 +68,6 @@ public static Predicate forType(FilterType type, TransitService tra public enum FilterType { NONE, - CURRENT_TRIMET_SERVICE_WEEK, + SUNDAY_TO_SUNDAY_SERVICE_WEEK, } } From cd73bd7605a6d03627b8461cc798619ac88636a4 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 13 Sep 2024 16:58:27 +0200 Subject: [PATCH 36/47] Extend schema for filtering routes by service dates --- .../apis/gtfs/datafetchers/StopImpl.java | 4 +++- .../org/opentripplanner/apis/gtfs/schema.graphqls | 11 ++++++++++- .../apis/gtfs/GraphQLIntegrationTest.java | 8 ++++++++ .../opentripplanner/apis/gtfs/queries/stops.graphql | 10 ++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java index 0730d2fbc91..b7f9cbce446 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java @@ -243,7 +243,9 @@ public DataFetcher platformCode() { @Override public DataFetcher> routes() { - return this::getRoutes; + return (env) -> { + var routes= this.getRoutes(env); + }; } @Override diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 927af19f8b1..844c609b526 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -2001,7 +2001,16 @@ type Stop implements Node & PlaceInterface { "Identifier of the platform, usually a number. This value is only present for stops that are part of a station" platformCode: String "Routes which pass through this stop" - routes: [Route!] + routes( + """ + Only include routes whose pattern operates on at least one service date specified by this filter. + + **Note**: A service date is a technical term useful for transit planning purposes and might not + correspond to a how a passenger thinks of a calendar date. For example, a night bus running + on Sunday morning at 1am to 3am, might have the previous Saturday's service date. + """ + serviceDates: LocalDateRangeInput, + ): [Route!] "Returns timetable of the specified pattern at this stop" stopTimesForPattern( "Id of the pattern" diff --git a/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java b/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java index 79590ca2775..0e0eb159c1b 100644 --- a/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java +++ b/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java @@ -28,6 +28,7 @@ import java.util.Comparator; import java.util.List; import java.util.Locale; +import java.util.Set; import java.util.stream.Stream; import javax.annotation.Nonnull; import org.glassfish.jersey.message.internal.OutboundJaxrsResponse; @@ -86,6 +87,7 @@ import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.network.BikeAccess; +import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.organization.Agency; import org.opentripplanner.transit.model.site.RegularStop; @@ -114,6 +116,7 @@ class GraphQLIntegrationTest { .of(A, B, C, D, E, F, G, H) .map(p -> (RegularStop) p.stop) .toList(); + private static final Route ROUTE = TransitModelForTest.route("a-route").build(); private static VehicleRentalStation VEHICLE_RENTAL_STATION = new TestVehicleRentalStationBuilder() .withVehicles(10) @@ -209,6 +212,11 @@ public List getModesOfStopLocation(StopLocation stop) { public TransitAlertService getTransitAlertService() { return alertService; } + + @Override + public Set getRoutesForStop(StopLocation stop) { + return Set.of(ROUTE); + } }; routes.forEach(transitService::addRoutes); diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/stops.graphql b/src/test/resources/org/opentripplanner/apis/gtfs/queries/stops.graphql index 5f3df71f8e7..ec320f8b86a 100644 --- a/src/test/resources/org/opentripplanner/apis/gtfs/queries/stops.graphql +++ b/src/test/resources/org/opentripplanner/apis/gtfs/queries/stops.graphql @@ -5,5 +5,15 @@ lon name vehicleMode + allRoutes: routes { + gtfsId + longName + shortName + } + routesWithinRange: routes(serviceDates: {start: "2024-09-10", end: "2024-09-10" }) { + gtfsId + longName + shortName + } } } From 7d9033d138d22a5895231ae15fed522a82648cbf Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 13 Sep 2024 17:21:56 +0200 Subject: [PATCH 37/47] Improve implementation --- .../apis/gtfs/datafetchers/StopImpl.java | 16 +++++++++++++-- .../apis/gtfs/generated/GraphQLTypes.java | 20 +++++++++++++++++++ .../apis/gtfs/queries/stops.graphql | 4 +++- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java index b7f9cbce446..d8a098b52a5 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java @@ -18,6 +18,8 @@ import org.opentripplanner.apis.gtfs.GraphQLUtils; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; +import org.opentripplanner.apis.gtfs.support.filter.PatternByDateFilterUtil; +import org.opentripplanner.apis.gtfs.support.time.LocalDateRangeUtil; import org.opentripplanner.framework.time.ServiceDateUtils; import org.opentripplanner.model.StopTimesInPattern; import org.opentripplanner.model.TripTimeOnDate; @@ -243,8 +245,18 @@ public DataFetcher platformCode() { @Override public DataFetcher> routes() { - return (env) -> { - var routes= this.getRoutes(env); + return env -> { + var args = new GraphQLTypes.GraphQLStopRoutesArgs(env.getArguments()); + var routes = getRoutes(env); + if (LocalDateRangeUtil.hasServiceDateFilter(args.getGraphQLServiceDates())) { + var filter = PatternByDateFilterUtil.ofGraphQL( + args.getGraphQLServiceDates(), + getTransitService(env) + ); + return filter.filterRoutes(routes.stream()); + } else { + return routes; + } }; } diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java index 67051444cdf..ed3e9afefc9 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java @@ -4231,6 +4231,26 @@ public void setGraphQLLanguage(String language) { } } + public static class GraphQLStopRoutesArgs { + + private GraphQLLocalDateRangeInput serviceDates; + + public GraphQLStopRoutesArgs(Map args) { + if (args != null) { + this.serviceDates = + new GraphQLLocalDateRangeInput((Map) args.get("serviceDates")); + } + } + + public GraphQLLocalDateRangeInput getGraphQLServiceDates() { + return this.serviceDates; + } + + public void setGraphQLServiceDates(GraphQLLocalDateRangeInput serviceDates) { + this.serviceDates = serviceDates; + } + } + public static class GraphQLStopStopTimesForPatternArgs { private String id; diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/queries/stops.graphql b/src/test/resources/org/opentripplanner/apis/gtfs/queries/stops.graphql index ec320f8b86a..af4fd904096 100644 --- a/src/test/resources/org/opentripplanner/apis/gtfs/queries/stops.graphql +++ b/src/test/resources/org/opentripplanner/apis/gtfs/queries/stops.graphql @@ -10,7 +10,9 @@ longName shortName } - routesWithinRange: routes(serviceDates: {start: "2024-09-10", end: "2024-09-10" }) { + routesWithinRange: routes( + serviceDates: { start: "2024-09-10", end: "2024-09-10" } + ) { gtfsId longName shortName From 8f03dbb0a53c39a75527e7645cb7c4e9240b46e8 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 16 Sep 2024 15:19:53 +0200 Subject: [PATCH 38/47] Convert from Stream to Collection --- .../opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java | 2 +- .../org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java | 2 +- .../transit/service/PatternByServiceDatesFilter.java | 4 ++-- .../transit/service/PatternByServiceDatesFilterTest.java | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java index d5551a9b902..0943fa309fc 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/QueryTypeImpl.java @@ -619,7 +619,7 @@ public DataFetcher> routes() { args.getGraphQLServiceDates(), transitService ); - routeStream = filter.filterRoutes(routeStream).stream(); + routeStream = filter.filterRoutes(routeStream.toList()).stream(); } return routeStream.toList(); }; diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java index d8a098b52a5..503899ba21a 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StopImpl.java @@ -253,7 +253,7 @@ public DataFetcher> routes() { args.getGraphQLServiceDates(), getTransitService(env) ); - return filter.filterRoutes(routes.stream()); + return filter.filterRoutes(routes); } else { return routes; } diff --git a/src/main/java/org/opentripplanner/transit/service/PatternByServiceDatesFilter.java b/src/main/java/org/opentripplanner/transit/service/PatternByServiceDatesFilter.java index 30c501af4a0..21890975acf 100644 --- a/src/main/java/org/opentripplanner/transit/service/PatternByServiceDatesFilter.java +++ b/src/main/java/org/opentripplanner/transit/service/PatternByServiceDatesFilter.java @@ -4,7 +4,6 @@ import java.util.Collection; import java.util.Objects; import java.util.function.Function; -import java.util.stream.Stream; import org.opentripplanner.apis.gtfs.model.LocalDateRange; import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.TripPattern; @@ -54,8 +53,9 @@ public Collection filterPatterns(Collection tripPatter * Filter the routes by listing all their patterns' service dates and checking if they * operate on the specified dates. */ - public Collection filterRoutes(Stream routeStream) { + public Collection filterRoutes(Collection routeStream) { return routeStream + .stream() .filter(r -> { var patterns = getPatternsForRoute.apply(r); return !this.filterPatterns(patterns).isEmpty(); diff --git a/src/test/java/org/opentripplanner/transit/service/PatternByServiceDatesFilterTest.java b/src/test/java/org/opentripplanner/transit/service/PatternByServiceDatesFilterTest.java index ffc734f6038..93f50ce5b1e 100644 --- a/src/test/java/org/opentripplanner/transit/service/PatternByServiceDatesFilterTest.java +++ b/src/test/java/org/opentripplanner/transit/service/PatternByServiceDatesFilterTest.java @@ -107,7 +107,7 @@ void filterRoutes(LocalDate start, LocalDate end, FilterExpectation expectation) var filter = defaultFilter(start, end); var filterInput = List.of(ROUTE_1); - var filterOutput = filter.filterRoutes(filterInput.stream()); + var filterOutput = filter.filterRoutes(filterInput); if (expectation == NOT_REMOVED) { assertEquals(filterOutput, filterInput); From 1a2fc413cee637b40be58ec7ce281759abebf2ef Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 16 Sep 2024 15:56:55 +0200 Subject: [PATCH 39/47] Add GraphQL assertion --- .../apis/gtfs/expectations/stops.json | 80 +++++++++++++++++-- 1 file changed, 72 insertions(+), 8 deletions(-) diff --git a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/stops.json b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/stops.json index 307b07b58aa..4e3d4c8a18c 100644 --- a/src/test/resources/org/opentripplanner/apis/gtfs/expectations/stops.json +++ b/src/test/resources/org/opentripplanner/apis/gtfs/expectations/stops.json @@ -6,56 +6,120 @@ "lat" : 5.0, "lon" : 8.0, "name" : "A", - "vehicleMode" : "BUS" + "vehicleMode" : "BUS", + "allRoutes" : [ + { + "gtfsId" : "F:a-route", + "longName" : null, + "shortName" : "Ra-route" + } + ], + "routesWithinRange" : [ ] }, { "gtfsId" : "F:B", "lat" : 6.0, "lon" : 8.5, "name" : "B", - "vehicleMode" : "BUS" + "vehicleMode" : "BUS", + "allRoutes" : [ + { + "gtfsId" : "F:a-route", + "longName" : null, + "shortName" : "Ra-route" + } + ], + "routesWithinRange" : [ ] }, { "gtfsId" : "F:C", "lat" : 7.0, "lon" : 9.0, "name" : "C", - "vehicleMode" : "BUS" + "vehicleMode" : "BUS", + "allRoutes" : [ + { + "gtfsId" : "F:a-route", + "longName" : null, + "shortName" : "Ra-route" + } + ], + "routesWithinRange" : [ ] }, { "gtfsId" : "F:D", "lat" : 8.0, "lon" : 9.5, "name" : "D", - "vehicleMode" : "BUS" + "vehicleMode" : "BUS", + "allRoutes" : [ + { + "gtfsId" : "F:a-route", + "longName" : null, + "shortName" : "Ra-route" + } + ], + "routesWithinRange" : [ ] }, { "gtfsId" : "F:E", "lat" : 9.0, "lon" : 10.0, "name" : "E", - "vehicleMode" : "BUS" + "vehicleMode" : "BUS", + "allRoutes" : [ + { + "gtfsId" : "F:a-route", + "longName" : null, + "shortName" : "Ra-route" + } + ], + "routesWithinRange" : [ ] }, { "gtfsId" : "F:F", "lat" : 9.0, "lon" : 10.5, "name" : "F", - "vehicleMode" : "BUS" + "vehicleMode" : "BUS", + "allRoutes" : [ + { + "gtfsId" : "F:a-route", + "longName" : null, + "shortName" : "Ra-route" + } + ], + "routesWithinRange" : [ ] }, { "gtfsId" : "F:G", "lat" : 9.5, "lon" : 11.0, "name" : "G", - "vehicleMode" : "BUS" + "vehicleMode" : "BUS", + "allRoutes" : [ + { + "gtfsId" : "F:a-route", + "longName" : null, + "shortName" : "Ra-route" + } + ], + "routesWithinRange" : [ ] }, { "gtfsId" : "F:H", "lat" : 10.0, "lon" : 11.5, "name" : "H", - "vehicleMode" : "BUS" + "vehicleMode" : "BUS", + "allRoutes" : [ + { + "gtfsId" : "F:a-route", + "longName" : null, + "shortName" : "Ra-route" + } + ], + "routesWithinRange" : [ ] } ] } From 1d189236ac21d816120535ee0da21ed402b0e2f5 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 17 Sep 2024 09:40:20 +0200 Subject: [PATCH 40/47] Format schema --- .../resources/org/opentripplanner/apis/gtfs/schema.graphqls | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 844c609b526..1b944253b05 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -2004,12 +2004,12 @@ type Stop implements Node & PlaceInterface { routes( """ Only include routes whose pattern operates on at least one service date specified by this filter. - + **Note**: A service date is a technical term useful for transit planning purposes and might not correspond to a how a passenger thinks of a calendar date. For example, a night bus running on Sunday morning at 1am to 3am, might have the previous Saturday's service date. """ - serviceDates: LocalDateRangeInput, + serviceDates: LocalDateRangeInput ): [Route!] "Returns timetable of the specified pattern at this stop" stopTimesForPattern( From 87991acf5bdb8ab73b898b0c0247d25a4eb726c3 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 17 Sep 2024 09:41:34 +0200 Subject: [PATCH 41/47] Update Javadoc --- .../opentripplanner/ext/vectortiles/layers/LayerFilters.java | 2 +- .../resources/org/opentripplanner/apis/gtfs/schema.graphqls | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/LayerFilters.java b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/LayerFilters.java index 9672a9810c1..7d63bbe5398 100644 --- a/src/ext/java/org/opentripplanner/ext/vectortiles/layers/LayerFilters.java +++ b/src/ext/java/org/opentripplanner/ext/vectortiles/layers/LayerFilters.java @@ -28,7 +28,7 @@ public class LayerFilters { /** * Returns a predicate which only includes stop which are visited by a pattern that is in the current - * TriMet service week, namely from Sunday to Sunday. + * "service week", which lasts from Sunday to Sunday. */ public static Predicate buildCurrentServiceWeekPredicate( Function> getPatternsForStop, diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 1b944253b05..63a9829bb19 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -2004,7 +2004,7 @@ type Stop implements Node & PlaceInterface { routes( """ Only include routes whose pattern operates on at least one service date specified by this filter. - + **Note**: A service date is a technical term useful for transit planning purposes and might not correspond to a how a passenger thinks of a calendar date. For example, a night bus running on Sunday morning at 1am to 3am, might have the previous Saturday's service date. From 86b48dbc46d95995b7a3e6330cef5f9602d87952 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 17 Sep 2024 16:39:48 +0200 Subject: [PATCH 42/47] Apply review feedback --- .../apis/gtfs/support/filter/PatternByDateFilterUtil.java | 2 +- .../resources/org/opentripplanner/apis/gtfs/schema.graphqls | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/support/filter/PatternByDateFilterUtil.java b/src/main/java/org/opentripplanner/apis/gtfs/support/filter/PatternByDateFilterUtil.java index 204cdbd0886..f3c0d6d0352 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/support/filter/PatternByDateFilterUtil.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/support/filter/PatternByDateFilterUtil.java @@ -6,7 +6,7 @@ import org.opentripplanner.transit.service.TransitService; /** - * Utility methods for instantiating a {@link PatternByServiceDatesFilter}/ + * Utility methods for instantiating a {@link PatternByServiceDatesFilter}. */ public class PatternByDateFilterUtil { diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 63a9829bb19..115eacccdfa 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -2003,7 +2003,7 @@ type Stop implements Node & PlaceInterface { "Routes which pass through this stop" routes( """ - Only include routes whose pattern operates on at least one service date specified by this filter. + Only include routes whose are operational on at least one service date specified by this filter. **Note**: A service date is a technical term useful for transit planning purposes and might not correspond to a how a passenger thinks of a calendar date. For example, a night bus running From 253bb179d415e4789b859d0080e1a5a4a7f14304 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 18 Sep 2024 07:17:18 +0200 Subject: [PATCH 43/47] Fix spelling Co-authored-by: Joel Lappalainen --- .../resources/org/opentripplanner/apis/gtfs/schema.graphqls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 115eacccdfa..78f18f4e654 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -2003,7 +2003,7 @@ type Stop implements Node & PlaceInterface { "Routes which pass through this stop" routes( """ - Only include routes whose are operational on at least one service date specified by this filter. + Only include routes which are operational on at least one service date specified by this filter. **Note**: A service date is a technical term useful for transit planning purposes and might not correspond to a how a passenger thinks of a calendar date. For example, a night bus running From 885e4aeb59152f410a9dc31380c7f33e4fdb8a91 Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Fri, 20 Sep 2024 11:55:09 +0000 Subject: [PATCH 44/47] Add changelog entry for #6003 [ci skip] --- doc/user/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/user/Changelog.md b/doc/user/Changelog.md index 844b89abc1e..0b394015088 100644 --- a/doc/user/Changelog.md +++ b/doc/user/Changelog.md @@ -6,6 +6,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle ## 2.7.0-SNAPSHOT (under development) - Extra leg when transferring at the same stop [#5984](https://github.com/opentripplanner/OpenTripPlanner/pull/5984) +- Filter vector tiles stops by current service week [#6003](https://github.com/opentripplanner/OpenTripPlanner/pull/6003) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.6.0 (2024-09-18) From 738969ff4c7a0a2bce3bc98f2585aebde160b029 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 01:31:30 +0000 Subject: [PATCH 45/47] Update dependency org.apache.maven.plugins:maven-gpg-plugin to v3.2.6 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d8d0138934b..706db0cd2c9 100644 --- a/pom.xml +++ b/pom.xml @@ -989,7 +989,7 @@ org.apache.maven.plugins maven-gpg-plugin - 3.2.5 + 3.2.6 sign-artifacts From 49db57e7fb7f4f185335e3df53ae793446aae750 Mon Sep 17 00:00:00 2001 From: Eivind Morris Bakke Date: Mon, 23 Sep 2024 14:56:27 +0200 Subject: [PATCH 46/47] Add a matcher API for filters in the transit service used for datedServiceJourneyQuery (#5713) * Adds a matcher API for the transit service and makes use of it in the DatedServiceJourneyQuery. This is the first simple implementation of a filter using the unified matcher API. * Adds an expression builder for building up a list of matchers simply and in a logically consistent manner. Also does List.copyOf instead of simple reassignment between TripOnServiceDateRequestBuilder and TripOnServiceDateRequest. * Adds convenience function for null and empty check for collections and removes get prefix from getters. * Addresses minor comments in code review. * Makes ContainsMatcher way more configurable and performant using suggestions from code review. Also improves documentation generally. * Addresses comments in PR. --- .../timetable/DatedServiceJourneyQuery.java | 80 +++------- .../framework/collection/CollectionUtils.java | 3 + .../framework/collection/ListUtils.java | 9 ++ .../api/request/TripOnServiceDateRequest.java | 77 +++++++++ .../TripOnServiceDateRequestBuilder.java | 66 ++++++++ .../transit/model/filter/expr/AndMatcher.java | 43 +++++ .../model/filter/expr/BinaryOperator.java | 37 +++++ .../model/filter/expr/ContainsMatcher.java | 55 +++++++ .../model/filter/expr/EqualityMatcher.java | 40 +++++ .../model/filter/expr/ExpressionBuilder.java | 37 +++++ .../transit/model/filter/expr/Matcher.java | 19 +++ .../transit/model/filter/expr/OrMatcher.java | 58 +++++++ .../TripOnServiceDateMatcherFactory.java | 70 ++++++++ .../service/DefaultTransitService.java | 20 +++ .../transit/service/TransitService.java | 9 ++ .../collection/CollectionUtilsTest.java | 9 ++ .../model/filter/expr/AndMatcherTest.java | 39 +++++ .../filter/expr/ContainsMatcherTest.java | 33 ++++ .../filter/expr/EqualityMatcherTest.java | 22 +++ .../model/filter/expr/OrMatcherTest.java | 31 ++++ .../TripOnServiceDateMatcherFactoryTest.java | 151 ++++++++++++++++++ 21 files changed, 849 insertions(+), 59 deletions(-) create mode 100644 src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequest.java create mode 100644 src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequestBuilder.java create mode 100644 src/main/java/org/opentripplanner/transit/model/filter/expr/AndMatcher.java create mode 100644 src/main/java/org/opentripplanner/transit/model/filter/expr/BinaryOperator.java create mode 100644 src/main/java/org/opentripplanner/transit/model/filter/expr/ContainsMatcher.java create mode 100644 src/main/java/org/opentripplanner/transit/model/filter/expr/EqualityMatcher.java create mode 100644 src/main/java/org/opentripplanner/transit/model/filter/expr/ExpressionBuilder.java create mode 100644 src/main/java/org/opentripplanner/transit/model/filter/expr/Matcher.java create mode 100644 src/main/java/org/opentripplanner/transit/model/filter/expr/OrMatcher.java create mode 100644 src/main/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactory.java create mode 100644 src/test/java/org/opentripplanner/transit/model/filter/expr/AndMatcherTest.java create mode 100644 src/test/java/org/opentripplanner/transit/model/filter/expr/ContainsMatcherTest.java create mode 100644 src/test/java/org/opentripplanner/transit/model/filter/expr/EqualityMatcherTest.java create mode 100644 src/test/java/org/opentripplanner/transit/model/filter/expr/OrMatcherTest.java create mode 100644 src/test/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactoryTest.java diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyQuery.java b/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyQuery.java index c3c8ba420e4..e3fbf90a35d 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyQuery.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/timetable/DatedServiceJourneyQuery.java @@ -10,13 +10,13 @@ import graphql.schema.GraphQLOutputType; import java.time.LocalDate; import java.util.List; -import java.util.stream.Stream; import org.opentripplanner.apis.transmodel.mapping.TransitIdMapper; import org.opentripplanner.apis.transmodel.model.EnumTypes; import org.opentripplanner.apis.transmodel.support.GqlUtil; +import org.opentripplanner.transit.api.request.TripOnServiceDateRequest; +import org.opentripplanner.transit.api.request.TripOnServiceDateRequestBuilder; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.transit.model.timetable.TripAlteration; -import org.opentripplanner.transit.model.timetable.TripOnServiceDate; /** * A GraphQL query for retrieving data on DatedServiceJourneys @@ -93,72 +93,34 @@ public static GraphQLFieldDefinition createQuery( .type(new GraphQLList(new GraphQLNonNull(Scalars.GraphQLString))) ) .dataFetcher(environment -> { - Stream stream = GqlUtil - .getTransitService(environment) - .getAllTripOnServiceDates() - .stream(); - + // The null safety checks are not needed here - they are taken care of by the request + // object, but reuse let's use the mapping method and leave this improvement until all APIs + // are pushing this check into the domain request. + var authorities = mapIDsToDomainNullSafe(environment.getArgument("authorities")); var lines = mapIDsToDomainNullSafe(environment.getArgument("lines")); var serviceJourneys = mapIDsToDomainNullSafe(environment.getArgument("serviceJourneys")); + var replacementFor = mapIDsToDomainNullSafe(environment.getArgument("replacementFor")); var privateCodes = environment.>getArgument("privateCodes"); var operatingDays = environment.>getArgument("operatingDays"); var alterations = environment.>getArgument("alterations"); - var authorities = mapIDsToDomainNullSafe(environment.getArgument("authorities")); - var replacementFor = mapIDsToDomainNullSafe(environment.getArgument("replacementFor")); - if (!lines.isEmpty()) { - stream = - stream.filter(tripOnServiceDate -> - lines.contains(tripOnServiceDate.getTrip().getRoute().getId()) - ); - } + TripOnServiceDateRequestBuilder tripOnServiceDateRequestBuilder = TripOnServiceDateRequest + .of() + .withOperatingDays(operatingDays) + .withAuthorities(authorities) + .withLines(lines) + .withServiceJourneys(serviceJourneys) + .withReplacementFor(replacementFor); - if (!serviceJourneys.isEmpty()) { - stream = - stream.filter(tripOnServiceDate -> - serviceJourneys.contains(tripOnServiceDate.getTrip().getId()) - ); - } + tripOnServiceDateRequestBuilder = + tripOnServiceDateRequestBuilder.withPrivateCodes(privateCodes); - if (privateCodes != null && !privateCodes.isEmpty()) { - stream = - stream.filter(tripOnServiceDate -> - privateCodes.contains(tripOnServiceDate.getTrip().getNetexInternalPlanningCode()) - ); - } + tripOnServiceDateRequestBuilder = + tripOnServiceDateRequestBuilder.withAlterations(alterations); - // At least one operationg day is required - var days = operatingDays.stream().toList(); - - stream = - stream.filter(tripOnServiceDate -> days.contains(tripOnServiceDate.getServiceDate())); - - if (alterations != null && !alterations.isEmpty()) { - stream = - stream.filter(tripOnServiceDate -> - alterations.contains(tripOnServiceDate.getTripAlteration()) - ); - } - - if (!authorities.isEmpty()) { - stream = - stream.filter(tripOnServiceDate -> - authorities.contains(tripOnServiceDate.getTrip().getRoute().getAgency().getId()) - ); - } - - if (!replacementFor.isEmpty()) { - stream = - stream.filter(tripOnServiceDate -> - !tripOnServiceDate.getReplacementFor().isEmpty() && - tripOnServiceDate - .getReplacementFor() - .stream() - .anyMatch(replacement -> replacementFor.contains(replacement.getId())) - ); - } - - return stream.toList(); + return GqlUtil + .getTransitService(environment) + .getTripOnServiceDates(tripOnServiceDateRequestBuilder.build()); }) .build(); } diff --git a/src/main/java/org/opentripplanner/framework/collection/CollectionUtils.java b/src/main/java/org/opentripplanner/framework/collection/CollectionUtils.java index 1e86f49770f..63f1df1aad5 100644 --- a/src/main/java/org/opentripplanner/framework/collection/CollectionUtils.java +++ b/src/main/java/org/opentripplanner/framework/collection/CollectionUtils.java @@ -37,6 +37,9 @@ public static String toString(@Nullable Collection c, String nullText) { /** * A null-safe version of isEmpty() for a collection. *

+ * The main strategy handling collections in OTP is to avoid nullable collection fields and use empty + * collections instead. So, before using this method check if the variable/field is indeed `@Nullable`. + *

* If the collection is {@code null} then {@code true} is returned. *

* If the collection is empty then {@code true} is returned. diff --git a/src/main/java/org/opentripplanner/framework/collection/ListUtils.java b/src/main/java/org/opentripplanner/framework/collection/ListUtils.java index 5964a1674e3..35b7e083695 100644 --- a/src/main/java/org/opentripplanner/framework/collection/ListUtils.java +++ b/src/main/java/org/opentripplanner/framework/collection/ListUtils.java @@ -69,4 +69,13 @@ public static List ofNullable(T input) { return List.of(input); } } + + /** + * This method converts the given collection to an instance of a List. If the input is + * {@code null} an empty collection is returned. If not the {@link List#copyOf(Collection)} is + * called. + */ + public static List nullSafeImmutableList(Collection c) { + return (c == null) ? List.of() : List.copyOf(c); + } } diff --git a/src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequest.java b/src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequest.java new file mode 100644 index 00000000000..6735dc1db29 --- /dev/null +++ b/src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequest.java @@ -0,0 +1,77 @@ +package org.opentripplanner.transit.api.request; + +import java.time.LocalDate; +import java.util.List; +import org.opentripplanner.framework.collection.ListUtils; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.timetable.TripAlteration; + +/* + * A request for trips on a specific service date. + * + * This request is used to retrieve TripsOnServiceDates that match the provided criteria. + * At least one operatingDay must be provided. + */ +public class TripOnServiceDateRequest { + + private final List operatingDays; + private final List authorities; + private final List lines; + private final List serviceJourneys; + private final List replacementFor; + private final List privateCodes; + private final List alterations; + + protected TripOnServiceDateRequest( + List operatingDays, + List authorities, + List lines, + List serviceJourneys, + List replacementFor, + List privateCodes, + List alterations + ) { + if (operatingDays == null || operatingDays.isEmpty()) { + throw new IllegalArgumentException("operatingDays must have at least one date"); + } + this.operatingDays = ListUtils.nullSafeImmutableList(operatingDays); + this.authorities = ListUtils.nullSafeImmutableList(authorities); + this.lines = ListUtils.nullSafeImmutableList(lines); + this.serviceJourneys = ListUtils.nullSafeImmutableList(serviceJourneys); + this.replacementFor = ListUtils.nullSafeImmutableList(replacementFor); + this.privateCodes = ListUtils.nullSafeImmutableList(privateCodes); + this.alterations = ListUtils.nullSafeImmutableList(alterations); + } + + public static TripOnServiceDateRequestBuilder of() { + return new TripOnServiceDateRequestBuilder(); + } + + public List authorities() { + return authorities; + } + + public List lines() { + return lines; + } + + public List serviceJourneys() { + return serviceJourneys; + } + + public List replacementFor() { + return replacementFor; + } + + public List privateCodes() { + return privateCodes; + } + + public List alterations() { + return alterations; + } + + public List operatingDays() { + return operatingDays; + } +} diff --git a/src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequestBuilder.java b/src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequestBuilder.java new file mode 100644 index 00000000000..7aa2644fdc9 --- /dev/null +++ b/src/main/java/org/opentripplanner/transit/api/request/TripOnServiceDateRequestBuilder.java @@ -0,0 +1,66 @@ +package org.opentripplanner.transit.api.request; + +import java.time.LocalDate; +import java.util.List; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.timetable.TripAlteration; + +public class TripOnServiceDateRequestBuilder { + + private List authorities; + private List lines; + private List serviceJourneys; + private List replacementFor; + private List privateCodes; + private List alterations; + private List operatingDays; + + protected TripOnServiceDateRequestBuilder() {} + + public TripOnServiceDateRequestBuilder withOperatingDays(List operatingDays) { + this.operatingDays = operatingDays; + return this; + } + + public TripOnServiceDateRequestBuilder withAuthorities(List authorities) { + this.authorities = authorities; + return this; + } + + public TripOnServiceDateRequestBuilder withLines(List lines) { + this.lines = lines; + return this; + } + + public TripOnServiceDateRequestBuilder withServiceJourneys(List serviceJourneys) { + this.serviceJourneys = serviceJourneys; + return this; + } + + public TripOnServiceDateRequestBuilder withReplacementFor(List replacementFor) { + this.replacementFor = replacementFor; + return this; + } + + public TripOnServiceDateRequestBuilder withPrivateCodes(List privateCodes) { + this.privateCodes = privateCodes; + return this; + } + + public TripOnServiceDateRequestBuilder withAlterations(List alterations) { + this.alterations = alterations; + return this; + } + + public TripOnServiceDateRequest build() { + return new TripOnServiceDateRequest( + operatingDays, + authorities, + lines, + serviceJourneys, + replacementFor, + privateCodes, + alterations + ); + } +} diff --git a/src/main/java/org/opentripplanner/transit/model/filter/expr/AndMatcher.java b/src/main/java/org/opentripplanner/transit/model/filter/expr/AndMatcher.java new file mode 100644 index 00000000000..74f38efa8b7 --- /dev/null +++ b/src/main/java/org/opentripplanner/transit/model/filter/expr/AndMatcher.java @@ -0,0 +1,43 @@ +package org.opentripplanner.transit.model.filter.expr; + +import static org.opentripplanner.transit.model.filter.expr.BinaryOperator.AND; + +import java.util.List; + +/** + * Takes a list of matchers and provides a single interface. All matchers in the list must match for + * the composite matcher to return a match. + * + * @param The entity type the AndMatcher matches. + */ +public final class AndMatcher implements Matcher { + + private final Matcher[] matchers; + + private AndMatcher(List> matchers) { + this.matchers = matchers.toArray(Matcher[]::new); + } + + public static Matcher of(List> matchers) { + // simplify a list of one element + if (matchers.size() == 1) { + return matchers.get(0); + } + return new AndMatcher<>(matchers); + } + + @Override + public boolean match(T entity) { + for (var m : matchers) { + if (!m.match(entity)) { + return false; + } + } + return true; + } + + @Override + public String toString() { + return "(" + AND.arrayToString(matchers) + ')'; + } +} diff --git a/src/main/java/org/opentripplanner/transit/model/filter/expr/BinaryOperator.java b/src/main/java/org/opentripplanner/transit/model/filter/expr/BinaryOperator.java new file mode 100644 index 00000000000..62f3fa30f27 --- /dev/null +++ b/src/main/java/org/opentripplanner/transit/model/filter/expr/BinaryOperator.java @@ -0,0 +1,37 @@ +package org.opentripplanner.transit.model.filter.expr; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * Used to concatenate matches with either the logical "AND" or "OR" operator. + */ +enum BinaryOperator { + AND("&"), + OR("|"); + + private final String token; + + BinaryOperator(String token) { + this.token = token; + } + + @Override + public String toString() { + return token; + } + + String arrayToString(T[] values) { + return colToString(Arrays.asList(values)); + } + + String colToString(Collection values) { + return values.stream().map(Objects::toString).collect(Collectors.joining(" " + token + " ")); + } + + String toString(T a, T b) { + return a.toString() + " " + token + " " + b.toString(); + } +} diff --git a/src/main/java/org/opentripplanner/transit/model/filter/expr/ContainsMatcher.java b/src/main/java/org/opentripplanner/transit/model/filter/expr/ContainsMatcher.java new file mode 100644 index 00000000000..ed3731897ec --- /dev/null +++ b/src/main/java/org/opentripplanner/transit/model/filter/expr/ContainsMatcher.java @@ -0,0 +1,55 @@ +package org.opentripplanner.transit.model.filter.expr; + +import java.util.function.Function; + +/** + * A matcher that applies a provided matcher to an iterable of child entities returned from the main + * entity that this matcher is for. + *

+ * If any of the iterable entities match the valueMatcher, then the match method returns true. In + * this way it is similar to an OR. + *

+ * @param The main entity type this matcher is applied to. + * @param The type of the child entities, for which there is a mapping from S to T. + */ +public class ContainsMatcher implements Matcher { + + private final String relationshipName; + private final Function> valuesProvider; + private final Matcher valueMatcher; + + /** + * @param relationshipName The name of the type of relationship between the main entity and the + * entity matched by the valueMatcher. + * @param valuesProvider The function that maps the entity being matched by this matcher (S) to + * the iterable of items being matched by valueMatcher. + * @param valueMatcher The matcher that is applied each of the iterable entities returned from the + * valuesProvider function. + */ + public ContainsMatcher( + String relationshipName, + Function> valuesProvider, + Matcher valueMatcher + ) { + this.relationshipName = relationshipName; + this.valuesProvider = valuesProvider; + this.valueMatcher = valueMatcher; + } + + public boolean match(S entity) { + if (valuesProvider.apply(entity) == null) { + return false; + } + for (T it : valuesProvider.apply(entity)) { + if (valueMatcher.match(it)) { + return true; + } + } + return false; + } + + @Override + public String toString() { + return "ContainsMatcher: " + relationshipName + ": " + valueMatcher.toString(); + } +} diff --git a/src/main/java/org/opentripplanner/transit/model/filter/expr/EqualityMatcher.java b/src/main/java/org/opentripplanner/transit/model/filter/expr/EqualityMatcher.java new file mode 100644 index 00000000000..1380131e07a --- /dev/null +++ b/src/main/java/org/opentripplanner/transit/model/filter/expr/EqualityMatcher.java @@ -0,0 +1,40 @@ +package org.opentripplanner.transit.model.filter.expr; + +import java.util.function.Function; + +/** + * A matcher that checks if a value is equal to another value derived from the matched entities. + *

+ * The derived entity value is provided by a function that takes the entity being matched as an argument. + *

+ * @param The type of the entity being matched. + * @param The type of the value that the matcher will test equality for. + */ +public class EqualityMatcher implements Matcher { + + private final String typeName; + private final V value; + private final Function valueProvider; + + /** + * @param typeName The typeName appears in the toString for easier debugging. + * @param value The value that this matcher will check equality for. + * @param valueProvider The function that maps the entity being matched by this matcher (T) to + * the value being matched by this matcher. + */ + public EqualityMatcher(String typeName, V value, Function valueProvider) { + this.typeName = typeName; + this.value = value; + this.valueProvider = valueProvider; + } + + @Override + public boolean match(T entity) { + return value.equals(valueProvider.apply(entity)); + } + + @Override + public String toString() { + return typeName + "==" + value; + } +} diff --git a/src/main/java/org/opentripplanner/transit/model/filter/expr/ExpressionBuilder.java b/src/main/java/org/opentripplanner/transit/model/filter/expr/ExpressionBuilder.java new file mode 100644 index 00000000000..b1b4d5be322 --- /dev/null +++ b/src/main/java/org/opentripplanner/transit/model/filter/expr/ExpressionBuilder.java @@ -0,0 +1,37 @@ +package org.opentripplanner.transit.model.filter.expr; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.function.Function; + +/** + * A builder for creating complex matchers composed of other matchers. + *

+ * This builder contains convenience methods for creating complex matchers from simpler ones. The + * resulting matcher "ands" together all the matchers it has built up. This supports the common + * pattern of narrowing results with multiple filters. + * + * @param The type of entity to match in the expression. + */ +public class ExpressionBuilder { + + private final List> matchers = new ArrayList<>(); + + public static ExpressionBuilder of() { + return new ExpressionBuilder<>(); + } + + public ExpressionBuilder or(Collection values, Function> valueProvider) { + if (values.isEmpty()) { + return this; + } + + matchers.add(OrMatcher.of(values.stream().map(valueProvider).toList())); + return this; + } + + public Matcher build() { + return AndMatcher.of(matchers); + } +} diff --git a/src/main/java/org/opentripplanner/transit/model/filter/expr/Matcher.java b/src/main/java/org/opentripplanner/transit/model/filter/expr/Matcher.java new file mode 100644 index 00000000000..db3c02296b9 --- /dev/null +++ b/src/main/java/org/opentripplanner/transit/model/filter/expr/Matcher.java @@ -0,0 +1,19 @@ +package org.opentripplanner.transit.model.filter.expr; + +/** + * Generic matcher interface - this is the root of the matcher type hierarchy. + *

+ * @param Domain type to match. + */ +@FunctionalInterface +public interface Matcher { + boolean match(T entity); + + static Matcher everything() { + return e -> true; + } + + static Matcher nothing() { + return e -> false; + } +} diff --git a/src/main/java/org/opentripplanner/transit/model/filter/expr/OrMatcher.java b/src/main/java/org/opentripplanner/transit/model/filter/expr/OrMatcher.java new file mode 100644 index 00000000000..62da7af63f4 --- /dev/null +++ b/src/main/java/org/opentripplanner/transit/model/filter/expr/OrMatcher.java @@ -0,0 +1,58 @@ +package org.opentripplanner.transit.model.filter.expr; + +import static org.opentripplanner.transit.model.filter.expr.BinaryOperator.OR; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Takes a list of matchers and provides a single interface. At least one of the matchers in the + * list must match for the composite matcher to return a match. + *

+ * @param The entity type the OrMatcher matches. + */ +public final class OrMatcher implements Matcher { + + private final Matcher[] matchers; + + private OrMatcher(List> matchers) { + this.matchers = matchers.toArray(Matcher[]::new); + } + + public static Matcher of(Matcher a, Matcher b) { + return of(List.of(a, b)); + } + + public static Matcher of(List> matchers) { + // Simplify if there is just one matcher in the list + if (matchers.size() == 1) { + return matchers.get(0); + } + // Collapse nested or matchers + var expr = new ArrayList>(); + for (Matcher it : matchers) { + if (it instanceof OrMatcher orMatcher) { + expr.addAll(Arrays.asList(orMatcher.matchers)); + } else { + expr.add(it); + } + } + return new OrMatcher<>(expr); + } + + @Override + public boolean match(T entity) { + for (var m : matchers) { + if (m.match(entity)) { + return true; + } + } + return false; + } + + @Override + public String toString() { + return "(" + OR.arrayToString(matchers) + ')'; + } +} diff --git a/src/main/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactory.java b/src/main/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactory.java new file mode 100644 index 00000000000..f86e7a1ff77 --- /dev/null +++ b/src/main/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactory.java @@ -0,0 +1,70 @@ +package org.opentripplanner.transit.model.filter.transit; + +import java.time.LocalDate; +import org.opentripplanner.transit.api.request.TripOnServiceDateRequest; +import org.opentripplanner.transit.model.filter.expr.ContainsMatcher; +import org.opentripplanner.transit.model.filter.expr.EqualityMatcher; +import org.opentripplanner.transit.model.filter.expr.ExpressionBuilder; +import org.opentripplanner.transit.model.filter.expr.Matcher; +import org.opentripplanner.transit.model.framework.AbstractTransitEntity; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.timetable.TripAlteration; +import org.opentripplanner.transit.model.timetable.TripOnServiceDate; + +/** + * A factory for creating matchers for TripOnServiceDate objects. + *

+ * This factory is used to create matchers for TripOnServiceDate objects based on a request. The + * resulting matcher can be used to filter a list of TripOnServiceDate objects. + */ +public class TripOnServiceDateMatcherFactory { + + public static Matcher of(TripOnServiceDateRequest request) { + ExpressionBuilder expr = ExpressionBuilder.of(); + + expr.or(request.operatingDays(), TripOnServiceDateMatcherFactory::operatingDay); + expr.or(request.authorities(), TripOnServiceDateMatcherFactory::authorityId); + expr.or(request.lines(), TripOnServiceDateMatcherFactory::routeId); + expr.or(request.serviceJourneys(), TripOnServiceDateMatcherFactory::serviceJourneyId); + expr.or(request.replacementFor(), TripOnServiceDateMatcherFactory::replacementFor); + expr.or(request.privateCodes(), TripOnServiceDateMatcherFactory::privateCode); + expr.or(request.alterations(), TripOnServiceDateMatcherFactory::alteration); + return expr.build(); + } + + static Matcher authorityId(FeedScopedId id) { + return new EqualityMatcher<>("agency", id, t -> t.getTrip().getRoute().getAgency().getId()); + } + + static Matcher routeId(FeedScopedId id) { + return new EqualityMatcher<>("route", id, t -> t.getTrip().getRoute().getId()); + } + + static Matcher serviceJourneyId(FeedScopedId id) { + return new EqualityMatcher<>("serviceJourney", id, t -> t.getTrip().getId()); + } + + static Matcher replacementFor(FeedScopedId id) { + return new ContainsMatcher<>( + "replacementForContains", + t -> t.getReplacementFor().stream().map(AbstractTransitEntity::getId).toList(), + new EqualityMatcher<>("replacementForIdEquals", id, (idToMatch -> idToMatch)) + ); + } + + static Matcher privateCode(String code) { + return new EqualityMatcher<>( + "privateCode", + code, + t -> t.getTrip().getNetexInternalPlanningCode() + ); + } + + static Matcher operatingDay(LocalDate date) { + return new EqualityMatcher<>("operatingDay", date, TripOnServiceDate::getServiceDate); + } + + static Matcher alteration(TripAlteration alteration) { + return new EqualityMatcher<>("alteration", alteration, TripOnServiceDate::getTripAlteration); + } +} diff --git a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java b/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java index 8fa18443bab..1738c66bab0 100644 --- a/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/DefaultTransitService.java @@ -35,8 +35,11 @@ import org.opentripplanner.routing.services.TransitAlertService; import org.opentripplanner.routing.stoptimes.ArrivalDeparture; import org.opentripplanner.routing.stoptimes.StopTimesHelper; +import org.opentripplanner.transit.api.request.TripOnServiceDateRequest; import org.opentripplanner.transit.model.basic.Notice; import org.opentripplanner.transit.model.basic.TransitMode; +import org.opentripplanner.transit.model.filter.expr.Matcher; +import org.opentripplanner.transit.model.filter.transit.TripOnServiceDateMatcherFactory; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; import org.opentripplanner.transit.model.framework.Deduplicator; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -591,6 +594,23 @@ public TripOnServiceDate getTripOnServiceDateForTripAndDay( return transitModelIndex.getTripOnServiceDateForTripAndDay().get(tripIdAndServiceDate); } + /** + * Returns a list of TripOnServiceDates that match the filtering defined in the request. + * + * @param request - A TripOnServiceDateRequest object with filtering defined. + * @return - A list of TripOnServiceDates + */ + @Override + public List getTripOnServiceDates(TripOnServiceDateRequest request) { + Matcher matcher = TripOnServiceDateMatcherFactory.of(request); + return transitModelIndex + .getTripOnServiceDateForTripAndDay() + .values() + .stream() + .filter(matcher::match) + .collect(Collectors.toList()); + } + /** * TODO OTP2 - This is NOT THREAD-SAFE and is used in the real-time updaters, we need to fix * this when doing the issue #3030. diff --git a/src/main/java/org/opentripplanner/transit/service/TransitService.java b/src/main/java/org/opentripplanner/transit/service/TransitService.java index 1836b5612d2..1e7c4ff8397 100644 --- a/src/main/java/org/opentripplanner/transit/service/TransitService.java +++ b/src/main/java/org/opentripplanner/transit/service/TransitService.java @@ -24,6 +24,7 @@ import org.opentripplanner.routing.algorithm.raptoradapter.transit.TransitLayer; import org.opentripplanner.routing.services.TransitAlertService; import org.opentripplanner.routing.stoptimes.ArrivalDeparture; +import org.opentripplanner.transit.api.request.TripOnServiceDateRequest; import org.opentripplanner.transit.model.basic.Notice; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.AbstractTransitEntity; @@ -307,4 +308,12 @@ List stopTimesForPatternAtStop( Set getAllServiceCodes(); Map getServiceCodesRunningForDate(); + + /** + * Returns a list of TripOnServiceDates that match the filtering defined in the request. + * + * @param request - A TripOnServiceDateRequest object with filtering defined. + * @return - A list of TripOnServiceDates + */ + List getTripOnServiceDates(TripOnServiceDateRequest request); } diff --git a/src/test/java/org/opentripplanner/framework/collection/CollectionUtilsTest.java b/src/test/java/org/opentripplanner/framework/collection/CollectionUtilsTest.java index ae33e493bcc..e2eaab520bc 100644 --- a/src/test/java/org/opentripplanner/framework/collection/CollectionUtilsTest.java +++ b/src/test/java/org/opentripplanner/framework/collection/CollectionUtilsTest.java @@ -1,6 +1,8 @@ package org.opentripplanner.framework.collection; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import com.google.type.Month; import java.time.Duration; @@ -15,6 +17,13 @@ class CollectionUtilsTest { public static final String NULL_STRING = ""; + @Test + void testIsEmpty() { + assertTrue(CollectionUtils.isEmpty(null)); + assertTrue(CollectionUtils.isEmpty(List.of())); + assertFalse(CollectionUtils.isEmpty(List.of(1))); + } + @Test void testToString() { assertEquals("", CollectionUtils.toString(null, NULL_STRING)); diff --git a/src/test/java/org/opentripplanner/transit/model/filter/expr/AndMatcherTest.java b/src/test/java/org/opentripplanner/transit/model/filter/expr/AndMatcherTest.java new file mode 100644 index 00000000000..c79260193ff --- /dev/null +++ b/src/test/java/org/opentripplanner/transit/model/filter/expr/AndMatcherTest.java @@ -0,0 +1,39 @@ +package org.opentripplanner.transit.model.filter.expr; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; +import org.junit.jupiter.api.Test; + +class AndMatcherTest { + + @Test + void testMatchSingleMatcher() { + var matcher = AndMatcher.of(List.of(new EqualityMatcher<>("int", 42, i -> i))); + assertTrue(matcher.match(42)); + assertFalse(matcher.match(43)); + } + + @Test + void testMatchMultiple() { + var matcher = AndMatcher.of( + List.of(new EqualityMatcher<>("int", 42, i -> i), new EqualityMatcher<>("int", 43, i -> i)) + ); + assertFalse(matcher.match(42)); + assertFalse(matcher.match(43)); + assertFalse(matcher.match(44)); + } + + @Test + void testMatchComposites() { + var matcher = AndMatcher.of( + List.of( + OrMatcher.of(List.of(new EqualityMatcher<>("int", 42, i -> i))), + OrMatcher.of(List.of(new EqualityMatcher<>("int", 43, i -> i))) + ) + ); + assertFalse(matcher.match(42)); + assertFalse(matcher.match(43)); + assertFalse(matcher.match(44)); + } +} diff --git a/src/test/java/org/opentripplanner/transit/model/filter/expr/ContainsMatcherTest.java b/src/test/java/org/opentripplanner/transit/model/filter/expr/ContainsMatcherTest.java new file mode 100644 index 00000000000..1709fc7bf86 --- /dev/null +++ b/src/test/java/org/opentripplanner/transit/model/filter/expr/ContainsMatcherTest.java @@ -0,0 +1,33 @@ +package org.opentripplanner.transit.model.filter.expr; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class ContainsMatcherTest { + + private static final Map> integerListMap = Map.of( + 1, + List.of("foo"), + 2, + List.of("bar"), + 3, + List.of("foo", "bar") + ); + + @Test + void testMatch() { + var matcher = new ContainsMatcher<>( + "contains", + integerListMap::get, + new EqualityMatcher<>("string", "foo", s -> s) + ); + + assertTrue(matcher.match(1)); + assertFalse(matcher.match(2)); + assertTrue(matcher.match(3)); + assertFalse(matcher.match(4)); + } +} diff --git a/src/test/java/org/opentripplanner/transit/model/filter/expr/EqualityMatcherTest.java b/src/test/java/org/opentripplanner/transit/model/filter/expr/EqualityMatcherTest.java new file mode 100644 index 00000000000..31d208a768a --- /dev/null +++ b/src/test/java/org/opentripplanner/transit/model/filter/expr/EqualityMatcherTest.java @@ -0,0 +1,22 @@ +package org.opentripplanner.transit.model.filter.expr; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class EqualityMatcherTest { + + @Test + void testMatchesPrimitive() { + var matcher = new EqualityMatcher<>("int", 42, i -> i); + assertTrue(matcher.match(42)); + assertFalse(matcher.match(43)); + } + + @Test + void testMatchesObject() { + var matcher = new EqualityMatcher<>("string", "foo", s -> s); + assertTrue(matcher.match("foo")); + assertFalse(matcher.match("bar")); + } +} diff --git a/src/test/java/org/opentripplanner/transit/model/filter/expr/OrMatcherTest.java b/src/test/java/org/opentripplanner/transit/model/filter/expr/OrMatcherTest.java new file mode 100644 index 00000000000..415f64e40ed --- /dev/null +++ b/src/test/java/org/opentripplanner/transit/model/filter/expr/OrMatcherTest.java @@ -0,0 +1,31 @@ +package org.opentripplanner.transit.model.filter.expr; + +import static org.junit.jupiter.api.Assertions.*; + +import java.util.List; +import org.junit.jupiter.api.Test; + +class OrMatcherTest { + + @Test + void testMatch() { + var matcher = OrMatcher.of( + new EqualityMatcher<>("int", 42, i -> i), + new EqualityMatcher<>("int", 43, i -> i) + ); + assertTrue(matcher.match(42)); + assertTrue(matcher.match(43)); + assertFalse(matcher.match(44)); + } + + @Test + void testMatchComposites() { + var matcher = OrMatcher.of( + AndMatcher.of(List.of(new EqualityMatcher<>("int", 42, i -> i))), + AndMatcher.of(List.of(new EqualityMatcher<>("int", 43, i -> i))) + ); + assertTrue(matcher.match(42)); + assertTrue(matcher.match(43)); + assertFalse(matcher.match(44)); + } +} diff --git a/src/test/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactoryTest.java b/src/test/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactoryTest.java new file mode 100644 index 00000000000..b7cb7aa6698 --- /dev/null +++ b/src/test/java/org/opentripplanner/transit/model/filter/transit/TripOnServiceDateMatcherFactoryTest.java @@ -0,0 +1,151 @@ +package org.opentripplanner.transit.model.filter.transit; + +import static org.junit.jupiter.api.Assertions.*; + +import java.time.LocalDate; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.opentripplanner.transit.api.request.TripOnServiceDateRequest; +import org.opentripplanner.transit.model.basic.TransitMode; +import org.opentripplanner.transit.model.filter.expr.Matcher; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.network.Route; +import org.opentripplanner.transit.model.organization.Agency; +import org.opentripplanner.transit.model.timetable.Trip; +import org.opentripplanner.transit.model.timetable.TripOnServiceDate; + +class TripOnServiceDateMatcherFactoryTest { + + private TripOnServiceDate tripOnServiceDateRut; + private TripOnServiceDate tripOnServiceDateRut2; + private TripOnServiceDate tripOnServiceDateAkt; + + @BeforeEach + void setup() { + tripOnServiceDateRut = + TripOnServiceDate + .of(new FeedScopedId("RUT:route:trip:date", "123")) + .withTrip( + Trip + .of(new FeedScopedId("RUT:route:trip", "1")) + .withRoute( + Route + .of(new FeedScopedId("RUT:route", "2")) + .withAgency( + Agency + .of(new FeedScopedId("RUT", "3")) + .withName("RUT") + .withTimezone("Europe/Oslo") + .build() + ) + .withMode(TransitMode.BUS) + .withShortName("BUS") + .build() + ) + .build() + ) + .withServiceDate(LocalDate.of(2024, 2, 22)) + .build(); + + tripOnServiceDateRut2 = + TripOnServiceDate + .of(new FeedScopedId("RUT:route:trip:date", "123")) + .withTrip( + Trip + .of(new FeedScopedId("RUT:route:trip2", "1")) + .withRoute( + Route + .of(new FeedScopedId("RUT:route", "2")) + .withAgency( + Agency + .of(new FeedScopedId("RUT", "3")) + .withName("RUT") + .withTimezone("Europe/Oslo") + .build() + ) + .withMode(TransitMode.BUS) + .withShortName("BUS") + .build() + ) + .build() + ) + .withServiceDate(LocalDate.of(2024, 2, 22)) + .build(); + + tripOnServiceDateAkt = + TripOnServiceDate + .of(new FeedScopedId("AKT:route:trip:date", "123")) + .withTrip( + Trip + .of(new FeedScopedId("AKT:route:trip", "1")) + .withRoute( + Route + .of(new FeedScopedId("AKT:route", "2")) + .withAgency( + Agency + .of(new FeedScopedId("AKT", "3")) + .withName("AKT") + .withTimezone("Europe/Oslo") + .build() + ) + .withMode(TransitMode.BUS) + .withShortName("BUS") + .build() + ) + .build() + ) + .withServiceDate(LocalDate.of(2024, 2, 22)) + .build(); + } + + @Test + void testMatchOperatingDays() { + TripOnServiceDateRequest request = TripOnServiceDateRequest + .of() + .withOperatingDays(List.of(LocalDate.of(2024, 2, 22))) + .build(); + + Matcher matcher = TripOnServiceDateMatcherFactory.of(request); + + assertTrue(matcher.match(tripOnServiceDateRut)); + assertTrue(matcher.match(tripOnServiceDateRut2)); + assertTrue(matcher.match(tripOnServiceDateAkt)); + } + + @Test + void testMatchMultiple() { + TripOnServiceDateRequest request = TripOnServiceDateRequest + .of() + .withOperatingDays(List.of(LocalDate.of(2024, 2, 22))) + .withAuthorities(List.of(new FeedScopedId("RUT", "3"))) + .withLines(List.of(new FeedScopedId("RUT:route", "2"))) + .withServiceJourneys(List.of(new FeedScopedId("RUT:route:trip", "1"))) + .build(); + + Matcher matcher = TripOnServiceDateMatcherFactory.of(request); + + assertTrue(matcher.match(tripOnServiceDateRut)); + assertFalse(matcher.match(tripOnServiceDateRut2)); + assertFalse(matcher.match(tripOnServiceDateAkt)); + } + + @Test + void testMatchMultipleServiceJourneyMatchers() { + TripOnServiceDateRequest request = TripOnServiceDateRequest + .of() + .withOperatingDays(List.of(LocalDate.of(2024, 2, 22))) + .withAuthorities(List.of(new FeedScopedId("RUT", "3"))) + .withLines(List.of(new FeedScopedId("RUT:route", "2"))) + .withServiceJourneys( + List.of(new FeedScopedId("RUT:route:trip", "1"), new FeedScopedId("RUT:route:trip2", "1")) + ) + .build(); + + Matcher matcher = TripOnServiceDateMatcherFactory.of(request); + + assertTrue(matcher.match(tripOnServiceDateRut)); + assertTrue(matcher.match(tripOnServiceDateRut2)); + assertFalse(matcher.match(tripOnServiceDateAkt)); + } +} From 4781641753119e5c9f0e65a03dbf1f1817b9439e Mon Sep 17 00:00:00 2001 From: OTP Changelog Bot Date: Mon, 23 Sep 2024 12:56:42 +0000 Subject: [PATCH 47/47] Add changelog entry for #5713 [ci skip] --- doc/user/Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/user/Changelog.md b/doc/user/Changelog.md index 0b394015088..4fbc424b418 100644 --- a/doc/user/Changelog.md +++ b/doc/user/Changelog.md @@ -7,6 +7,7 @@ based on merged pull requests. Search GitHub issues and pull requests for smalle - Extra leg when transferring at the same stop [#5984](https://github.com/opentripplanner/OpenTripPlanner/pull/5984) - Filter vector tiles stops by current service week [#6003](https://github.com/opentripplanner/OpenTripPlanner/pull/6003) +- Add a matcher API for filters in the transit service used for datedServiceJourneyQuery [#5713](https://github.com/opentripplanner/OpenTripPlanner/pull/5713) [](AUTOMATIC_CHANGELOG_PLACEHOLDER_DO_NOT_REMOVE) ## 2.6.0 (2024-09-18)