From 470dbe209ebe31b3a19a5666ec16d5601955ee63 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 8 Jul 2024 14:44:54 +0200 Subject: [PATCH 01/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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/43] 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 d5583b843c5d9730236acfb08788255abcb147f4 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 9 Sep 2024 09:37:12 +0200 Subject: [PATCH 10/43] 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 11/43] 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 12/43] 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 13/43] 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 14/43] 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 15/43] 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 16/43] 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 0b5f0a84d4912cf6bef91cf54dedd366f69c1227 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 10 Sep 2024 16:47:18 +0200 Subject: [PATCH 17/43] 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 18/43] 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 19/43] 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 20/43] 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 21/43] 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 22/43] 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 23/43] 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 24/43] 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 49db57e7fb7f4f185335e3df53ae793446aae750 Mon Sep 17 00:00:00 2001 From: Eivind Morris Bakke Date: Mon, 23 Sep 2024 14:56:27 +0200 Subject: [PATCH 25/43] 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 26/43] 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) From c61819a200ed8ee4cb6b9bee8cc70a1a786e178c Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Thu, 19 Sep 2024 23:23:14 +0200 Subject: [PATCH 27/43] Return transit model timezone in server info --- .../api/model/serverinfo/ApiServerInfo.java | 5 +++- .../api/resource/ServerInfo.java | 30 +++++++++++++------ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/opentripplanner/api/model/serverinfo/ApiServerInfo.java b/src/main/java/org/opentripplanner/api/model/serverinfo/ApiServerInfo.java index e90c0e37fdf..e4b42d48e59 100644 --- a/src/main/java/org/opentripplanner/api/model/serverinfo/ApiServerInfo.java +++ b/src/main/java/org/opentripplanner/api/model/serverinfo/ApiServerInfo.java @@ -1,5 +1,6 @@ package org.opentripplanner.api.model.serverinfo; +import java.time.ZoneId; import org.opentripplanner.model.projectinfo.OtpProjectInfo; public class ApiServerInfo { @@ -10,13 +11,15 @@ public class ApiServerInfo { public final ApiVersionControlInfo versionControl; public final ApiConfigInfo config; public final String otpSerializationVersionId; + public final String transitTimeZone; - public ApiServerInfo(String cpuName, int nCores, OtpProjectInfo projectInfo) { + public ApiServerInfo(String cpuName, int nCores, OtpProjectInfo projectInfo, ZoneId transitTimeZone) { this.cpuName = cpuName; this.nCores = nCores; this.version = new ApiProjectVersion(projectInfo.version); this.versionControl = new ApiVersionControlInfo(projectInfo.versionControl); this.config = new ApiConfigInfo(projectInfo); this.otpSerializationVersionId = projectInfo.getOtpSerializationVersionId(); + this.transitTimeZone = transitTimeZone.toString(); } } diff --git a/src/main/java/org/opentripplanner/api/resource/ServerInfo.java b/src/main/java/org/opentripplanner/api/resource/ServerInfo.java index bc8d91d4780..c11d9c8158f 100644 --- a/src/main/java/org/opentripplanner/api/resource/ServerInfo.java +++ b/src/main/java/org/opentripplanner/api/resource/ServerInfo.java @@ -3,19 +3,29 @@ import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.Context; import jakarta.ws.rs.core.MediaType; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; +import java.time.ZoneId; import org.opentripplanner.api.model.serverinfo.ApiServerInfo; import org.opentripplanner.model.projectinfo.OtpProjectInfo; +import org.opentripplanner.standalone.api.OtpServerRequestContext; @Path("/") public class ServerInfo { - private static final ApiServerInfo SERVER_INFO = createServerInfo(); + private final ZoneId timeZone; + private static final String cpuName; + private static final int nCores ; + + public ServerInfo(@Context OtpServerRequestContext serverContext) { + this.timeZone = serverContext.transitService().getTimeZone(); + } + /** * Determine the OTP version and CPU type of the running server. This information should not @@ -23,28 +33,30 @@ public class ServerInfo { * available before the graph is loaded, so for this to work this class should not be loaded * BEFORE that. */ - public static ApiServerInfo createServerInfo() { - String cpuName = "unknown"; - int nCores = 0; + static { + var cpu = "unknown"; + int cores = 0; try { InputStream fis = new FileInputStream("/proc/cpuinfo"); BufferedReader br = new BufferedReader(new InputStreamReader(fis, StandardCharsets.UTF_8)); String line; while ((line = br.readLine()) != null) { if (line.startsWith("model name")) { - cpuName = line.split(": ")[1]; - nCores += 1; + cpu = line.split(": ")[1]; + cores+= 1; } } fis.close(); } catch (Exception ignore) {} - - return new ApiServerInfo(cpuName, nCores, OtpProjectInfo.projectInfo()); + cpuName = cpu; + nCores = cores; } + + @GET @Produces(MediaType.APPLICATION_JSON) public ApiServerInfo getServerInfo() { - return SERVER_INFO; + return new ApiServerInfo(cpuName, nCores, OtpProjectInfo.projectInfo(), timeZone); } } From d6f1b806c687f07d159654ab67320fa2bc7cc068 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Fri, 20 Sep 2024 09:42:35 +0200 Subject: [PATCH 28/43] Use react to fetch time zone --- client/.env | 1 + client/.env.development | 3 ++- client/src/hooks/useTimeZone.ts | 19 +++++++++++++++++++ client/src/util/formatTime.ts | 3 +++ 4 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 client/src/hooks/useTimeZone.ts diff --git a/client/.env b/client/.env index 2f5d271b1e4..a4fbf511e26 100644 --- a/client/.env +++ b/client/.env @@ -1,3 +1,4 @@ VITE_API_URL=/otp/transmodel/v3 VITE_DEBUG_STYLE_URL=/otp/routers/default/inspector/vectortile/style.json VITE_GRAPHIQL_URL=/graphiql?flavor=transmodel +VITE_SERVER_INFO_URL=/otp/ diff --git a/client/.env.development b/client/.env.development index 1cb7d9235e3..70ad81eb7dd 100644 --- a/client/.env.development +++ b/client/.env.development @@ -1,3 +1,4 @@ VITE_API_URL=http://localhost:8080/otp/transmodel/v3 VITE_DEBUG_STYLE_URL=http://localhost:8080/otp/routers/default/inspector/vectortile/style.json -VITE_GRAPHIQL_URL=http://localhost:8080/graphiql?flavor=transmodel \ No newline at end of file +VITE_GRAPHIQL_URL=http://localhost:8080/graphiql?flavor=transmodel +VITE_SERVER_INFO_URL=http://localhost:8080/otp/ diff --git a/client/src/hooks/useTimeZone.ts b/client/src/hooks/useTimeZone.ts new file mode 100644 index 00000000000..36ab9d9d12a --- /dev/null +++ b/client/src/hooks/useTimeZone.ts @@ -0,0 +1,19 @@ +import { useEffect, useState } from 'react'; + +type ServerInfo = { + transitTimeZone: string; +}; + +const fetchServerInfo = (): Promise => fetch('http://localhost:8080/otp/').then((r) => r.json()); + +export const useTimeZone = () => { + const [data, setData] = useState(null); + useEffect(() => { + const fetchData = async () => { + setData(await fetchServerInfo()); + }; + fetchData(); + }, []); + + return data?.transitTimeZone || Intl.DateTimeFormat().resolvedOptions().timeZone; +}; diff --git a/client/src/util/formatTime.ts b/client/src/util/formatTime.ts index 1849640fe3f..1b14ab103c6 100644 --- a/client/src/util/formatTime.ts +++ b/client/src/util/formatTime.ts @@ -1,3 +1,5 @@ +import {useTimeZone} from "../hooks/useTimeZone.ts"; + /** * Format departure and arrival times from scalar dateTime strings * @@ -9,5 +11,6 @@ export function formatTime(dateTime: string, style?: 'short' | 'medium') { return parsed.toLocaleTimeString('en-US', { timeStyle: style ? style : parsed.getSeconds() === 0 ? 'short' : 'medium', hourCycle: 'h24', + timeZone: useTimeZone() }); } From 719dde7687c59e141834a6cbd0daed5aafc2d1f1 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 23 Sep 2024 14:22:34 +0200 Subject: [PATCH 29/43] Use polyfill, combine datetime into a single input --- client/package-lock.json | 18 +++++++++ client/package.json | 1 + .../components/SearchBar/DateInputField.tsx | 40 ------------------- client/src/components/SearchBar/SearchBar.tsx | 2 - .../components/SearchBar/TimeInputField.tsx | 24 +++++++---- client/src/hooks/useTimeZone.ts | 17 +------- 6 files changed, 37 insertions(+), 65 deletions(-) delete mode 100644 client/src/components/SearchBar/DateInputField.tsx diff --git a/client/package-lock.json b/client/package-lock.json index 5619317e0bd..00490ce16d6 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "dependencies": { "@googlemaps/polyline-codec": "1.0.28", + "@js-temporal/polyfill": "0.4.4", "bootstrap": "5.3.3", "graphql": "16.9.0", "graphql-request": "7.1.0", @@ -2958,6 +2959,18 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@js-temporal/polyfill": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@js-temporal/polyfill/-/polyfill-0.4.4.tgz", + "integrity": "sha512-2X6bvghJ/JAoZO52lbgyAPFj8uCflhTo2g7nkFzEQdXd/D8rEeD4HtmTEpmtGCva260fcd66YNXBOYdnmHqSOg==", + "dependencies": { + "jsbi": "^4.3.0", + "tslib": "^2.4.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@kamilkisiela/fast-url-parser": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/@kamilkisiela/fast-url-parser/-/fast-url-parser-1.1.4.tgz", @@ -8269,6 +8282,11 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbi": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/jsbi/-/jsbi-4.3.0.tgz", + "integrity": "sha512-SnZNcinB4RIcnEyZqFPdGPVgrg2AcnykiBy0sHVJQKHYeaLUvi3Exj+iaPpLnFVkDPZIV4U0yvgC9/R4uEAZ9g==" + }, "node_modules/jsdom": { "version": "25.0.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.0.tgz", diff --git a/client/package.json b/client/package.json index 2cd0d1f8937..0e822b4a641 100644 --- a/client/package.json +++ b/client/package.json @@ -18,6 +18,7 @@ }, "dependencies": { "@googlemaps/polyline-codec": "1.0.28", + "@js-temporal/polyfill": "0.4.4", "bootstrap": "5.3.3", "graphql": "16.9.0", "graphql-request": "7.1.0", diff --git a/client/src/components/SearchBar/DateInputField.tsx b/client/src/components/SearchBar/DateInputField.tsx deleted file mode 100644 index 0b0eca38869..00000000000 --- a/client/src/components/SearchBar/DateInputField.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { Form } from 'react-bootstrap'; -import { TripQueryVariables } from '../../gql/graphql.ts'; -import { ChangeEvent, useCallback, useMemo } from 'react'; - -export function DateInputField({ - tripQueryVariables, - setTripQueryVariables, -}: { - tripQueryVariables: TripQueryVariables; - setTripQueryVariables: (tripQueryVariables: TripQueryVariables) => void; -}) { - const current = useMemo( - () => new Date(tripQueryVariables.dateTime).toISOString().split('T')[0], - [tripQueryVariables.dateTime], - ); - - const onChange = useCallback( - (event: ChangeEvent) => { - const oldDate = new Date(tripQueryVariables.dateTime); - const newDate = new Date(event.target.value); - - newDate.setHours(oldDate.getHours(), oldDate.getMinutes(), oldDate.getSeconds()); - - setTripQueryVariables({ - ...tripQueryVariables, - dateTime: newDate.toISOString(), - }); - }, - [tripQueryVariables, setTripQueryVariables], - ); - - return ( - - - Date - - - - ); -} diff --git a/client/src/components/SearchBar/SearchBar.tsx b/client/src/components/SearchBar/SearchBar.tsx index dfcbc6ac36e..bb6b47abc3f 100644 --- a/client/src/components/SearchBar/SearchBar.tsx +++ b/client/src/components/SearchBar/SearchBar.tsx @@ -3,7 +3,6 @@ import { ServerInfo, TripQueryVariables } from '../../gql/graphql.ts'; import { LocationInputField } from './LocationInputField.tsx'; import { DepartureArrivalSelect } from './DepartureArrivalSelect.tsx'; import { TimeInputField } from './TimeInputField.tsx'; -import { DateInputField } from './DateInputField.tsx'; import { SearchWindowInput } from './SearchWindowInput.tsx'; import { AccessSelect } from './AccessSelect.tsx'; import { EgressSelect } from './EgressSelect.tsx'; @@ -41,7 +40,6 @@ export function SearchBar({ onRoute, tripQueryVariables, setTripQueryVariables, - diff --git a/client/src/components/SearchBar/TimeInputField.tsx b/client/src/components/SearchBar/TimeInputField.tsx index 71bb7325340..af2fcfd150c 100644 --- a/client/src/components/SearchBar/TimeInputField.tsx +++ b/client/src/components/SearchBar/TimeInputField.tsx @@ -1,6 +1,8 @@ import { Form } from 'react-bootstrap'; import { TripQueryVariables } from '../../gql/graphql.ts'; import { ChangeEvent, useCallback, useMemo } from 'react'; +import { Temporal } from '@js-temporal/polyfill'; +import { useTimeZone } from '../../hooks/useTimeZone.ts'; export function TimeInputField({ tripQueryVariables, @@ -10,19 +12,27 @@ export function TimeInputField({ setTripQueryVariables: (tripQueryVariables: TripQueryVariables) => void; }) { const current = useMemo( - () => new Date(tripQueryVariables.dateTime).toTimeString().split(' ')[0], + () => + Temporal.Instant.from(tripQueryVariables.dateTime) + .toZonedDateTime({ + calendar: 'gregory', + timeZone: useTimeZone(), + }) + .toPlainDateTime() + .toString({ smallestUnit: 'minute', calendarName: 'never' }), [tripQueryVariables.dateTime], ); const onChange = useCallback( (event: ChangeEvent) => { - const timeComponents = event.target.value.split(':'); - const newDate = new Date(tripQueryVariables.dateTime); - newDate.setHours(Number(timeComponents[0]), Number(timeComponents[1]), Number(timeComponents[2])); + const dateTime = Temporal.PlainDateTime.from(event.target.value) + .toZonedDateTime(useTimeZone()) + .toString({ calendarName: 'never', timeZoneName: 'never' }); + console.log(dateTime); setTripQueryVariables({ ...tripQueryVariables, - dateTime: newDate.toISOString(), + dateTime: dateTime, }); }, [tripQueryVariables, setTripQueryVariables], @@ -31,9 +41,9 @@ export function TimeInputField({ return ( - Time + Time ({useTimeZone()}) - + ); } diff --git a/client/src/hooks/useTimeZone.ts b/client/src/hooks/useTimeZone.ts index 36ab9d9d12a..b88eb0afb42 100644 --- a/client/src/hooks/useTimeZone.ts +++ b/client/src/hooks/useTimeZone.ts @@ -1,19 +1,4 @@ -import { useEffect, useState } from 'react'; - -type ServerInfo = { - transitTimeZone: string; -}; - -const fetchServerInfo = (): Promise => fetch('http://localhost:8080/otp/').then((r) => r.json()); - export const useTimeZone = () => { - const [data, setData] = useState(null); - useEffect(() => { - const fetchData = async () => { - setData(await fetchServerInfo()); - }; - fetchData(); - }, []); - return data?.transitTimeZone || Intl.DateTimeFormat().resolvedOptions().timeZone; + return "America/Los_Angeles" }; From e75409dd34b06d9af4bbb759263d75464910e5c6 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 23 Sep 2024 14:24:49 +0200 Subject: [PATCH 30/43] Simplify time zone display --- client/src/components/SearchBar/TimeInputField.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/components/SearchBar/TimeInputField.tsx b/client/src/components/SearchBar/TimeInputField.tsx index af2fcfd150c..8c7db133f91 100644 --- a/client/src/components/SearchBar/TimeInputField.tsx +++ b/client/src/components/SearchBar/TimeInputField.tsx @@ -40,8 +40,8 @@ export function TimeInputField({ return ( - - Time ({useTimeZone()}) + + Time From db17fab64ae5c6e230998e05ec9b70434ecb834b Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 23 Sep 2024 22:39:59 +0200 Subject: [PATCH 31/43] Store time zone in context --- .../ItineraryList/ItineraryHeaderContent.tsx | 9 ++-- .../ItineraryList/ItineraryListContainer.tsx | 6 +++ .../src/components/ItineraryList/LegTime.tsx | 9 ++-- ...eInputField.tsx => DateTimeInputField.tsx} | 17 +++---- client/src/components/SearchBar/SearchBar.tsx | 4 +- client/src/hooks/TimeZoneContext.ts | 3 ++ client/src/hooks/useTimeZone.ts | 17 ++++++- client/src/screens/App.tsx | 47 ++++++++++--------- client/src/style.css | 6 +++ client/src/util/formatTime.ts | 6 +-- 10 files changed, 80 insertions(+), 44 deletions(-) rename client/src/components/SearchBar/{TimeInputField.tsx => DateTimeInputField.tsx} (74%) create mode 100644 client/src/hooks/TimeZoneContext.ts diff --git a/client/src/components/ItineraryList/ItineraryHeaderContent.tsx b/client/src/components/ItineraryList/ItineraryHeaderContent.tsx index cf3ca227b63..0788ca1974e 100644 --- a/client/src/components/ItineraryList/ItineraryHeaderContent.tsx +++ b/client/src/components/ItineraryList/ItineraryHeaderContent.tsx @@ -1,8 +1,9 @@ import { TripPattern } from '../../gql/graphql.ts'; import { TIME_BOX_WIDTH, useHeaderContentStyleCalculations } from './useHeaderContentStyleCalculations.ts'; import { ItineraryHeaderLegContent } from './ItineraryHeaderLegContent.tsx'; -import { useMemo } from 'react'; +import { useContext, useMemo } from 'react'; import { formatTime } from '../../util/formatTime.ts'; +import { TimeZoneContext } from '../../hooks/TimeZoneContext.ts'; export function ItineraryHeaderContent({ tripPattern, @@ -24,13 +25,15 @@ export function ItineraryHeaderContent({ latestEndTime, ); + const timeZone = useContext(TimeZoneContext); + const formattedStartTime = useMemo( - () => formatTime(tripPattern.expectedStartTime, 'short'), + () => formatTime(tripPattern.expectedStartTime, timeZone, 'short'), [tripPattern.expectedStartTime], ); const formattedEndTime = useMemo( - () => formatTime(tripPattern.expectedEndTime, 'short'), + () => formatTime(tripPattern.expectedEndTime, timeZone, 'short'), [tripPattern.expectedEndTime], ); diff --git a/client/src/components/ItineraryList/ItineraryListContainer.tsx b/client/src/components/ItineraryList/ItineraryListContainer.tsx index feaf29aa514..b474d2eb5ec 100644 --- a/client/src/components/ItineraryList/ItineraryListContainer.tsx +++ b/client/src/components/ItineraryList/ItineraryListContainer.tsx @@ -5,6 +5,8 @@ import { ItineraryHeaderContent } from './ItineraryHeaderContent.tsx'; import { useEarliestAndLatestTimes } from './useEarliestAndLatestTimes.ts'; import { ItineraryDetails } from './ItineraryDetails.tsx'; import { ItineraryPaginationControl } from './ItineraryPaginationControl.tsx'; +import { useContext } from 'react'; +import { TimeZoneContext } from '../../hooks/TimeZoneContext.ts'; export function ItineraryListContainer({ tripQueryResult, @@ -21,6 +23,7 @@ export function ItineraryListContainer({ }) { const [earliestStartTime, latestEndTime] = useEarliestAndLatestTimes(tripQueryResult); const { containerRef, containerWidth } = useContainerWidth(); + const timeZone = useContext(TimeZoneContext); return (

@@ -56,6 +59,9 @@ export function ItineraryListContainer({ ))} +
+ All times in {timeZone} +
); } diff --git a/client/src/components/ItineraryList/LegTime.tsx b/client/src/components/ItineraryList/LegTime.tsx index 0a574a7bccc..19d852a97be 100644 --- a/client/src/components/ItineraryList/LegTime.tsx +++ b/client/src/components/ItineraryList/LegTime.tsx @@ -1,4 +1,6 @@ import { formatTime } from '../../util/formatTime.ts'; +import { useContext } from 'react'; +import { TimeZoneContext } from '../../hooks/TimeZoneContext.ts'; export function LegTime({ aimedTime, @@ -9,18 +11,19 @@ export function LegTime({ expectedTime: string; hasRealtime: boolean; }) { + const timeZone = useContext(TimeZoneContext); return aimedTime !== expectedTime ? ( <> - {formatTime(expectedTime, 'short')} + {formatTime(expectedTime, timeZone, 'short')} - {formatTime(aimedTime, 'short')} + {formatTime(aimedTime, timeZone, 'short')} ) : ( - {formatTime(expectedTime, 'short')} + {formatTime(expectedTime, timeZone, 'short')} {hasRealtime && (on time)} ); diff --git a/client/src/components/SearchBar/TimeInputField.tsx b/client/src/components/SearchBar/DateTimeInputField.tsx similarity index 74% rename from client/src/components/SearchBar/TimeInputField.tsx rename to client/src/components/SearchBar/DateTimeInputField.tsx index 8c7db133f91..c7e77ee8f05 100644 --- a/client/src/components/SearchBar/TimeInputField.tsx +++ b/client/src/components/SearchBar/DateTimeInputField.tsx @@ -1,23 +1,21 @@ import { Form } from 'react-bootstrap'; import { TripQueryVariables } from '../../gql/graphql.ts'; -import { ChangeEvent, useCallback, useMemo } from 'react'; +import { ChangeEvent, useCallback, useContext, useMemo } from 'react'; import { Temporal } from '@js-temporal/polyfill'; -import { useTimeZone } from '../../hooks/useTimeZone.ts'; +import { TimeZoneContext } from '../../hooks/TimeZoneContext.ts'; -export function TimeInputField({ +export function DateTimeInputField({ tripQueryVariables, setTripQueryVariables, }: { tripQueryVariables: TripQueryVariables; setTripQueryVariables: (tripQueryVariables: TripQueryVariables) => void; }) { + const timeZone = useContext(TimeZoneContext); const current = useMemo( () => Temporal.Instant.from(tripQueryVariables.dateTime) - .toZonedDateTime({ - calendar: 'gregory', - timeZone: useTimeZone(), - }) + .toZonedDateTimeISO(timeZone) .toPlainDateTime() .toString({ smallestUnit: 'minute', calendarName: 'never' }), [tripQueryVariables.dateTime], @@ -26,10 +24,9 @@ export function TimeInputField({ const onChange = useCallback( (event: ChangeEvent) => { const dateTime = Temporal.PlainDateTime.from(event.target.value) - .toZonedDateTime(useTimeZone()) + .toZonedDateTime(timeZone) .toString({ calendarName: 'never', timeZoneName: 'never' }); - console.log(dateTime); setTripQueryVariables({ ...tripQueryVariables, dateTime: dateTime, @@ -40,7 +37,7 @@ export function TimeInputField({ return ( - + Time diff --git a/client/src/components/SearchBar/SearchBar.tsx b/client/src/components/SearchBar/SearchBar.tsx index bb6b47abc3f..ca072fa5589 100644 --- a/client/src/components/SearchBar/SearchBar.tsx +++ b/client/src/components/SearchBar/SearchBar.tsx @@ -2,7 +2,7 @@ import { Button, Spinner } from 'react-bootstrap'; import { ServerInfo, TripQueryVariables } from '../../gql/graphql.ts'; import { LocationInputField } from './LocationInputField.tsx'; import { DepartureArrivalSelect } from './DepartureArrivalSelect.tsx'; -import { TimeInputField } from './TimeInputField.tsx'; +import { DateTimeInputField } from './DateTimeInputField.tsx'; import { SearchWindowInput } from './SearchWindowInput.tsx'; import { AccessSelect } from './AccessSelect.tsx'; import { EgressSelect } from './EgressSelect.tsx'; @@ -39,7 +39,7 @@ export function SearchBar({ onRoute, tripQueryVariables, setTripQueryVariables, - + diff --git a/client/src/hooks/TimeZoneContext.ts b/client/src/hooks/TimeZoneContext.ts new file mode 100644 index 00000000000..6a40921ebae --- /dev/null +++ b/client/src/hooks/TimeZoneContext.ts @@ -0,0 +1,3 @@ +import { createContext } from 'react'; + +export const TimeZoneContext = createContext('UTC'); diff --git a/client/src/hooks/useTimeZone.ts b/client/src/hooks/useTimeZone.ts index b88eb0afb42..36ab9d9d12a 100644 --- a/client/src/hooks/useTimeZone.ts +++ b/client/src/hooks/useTimeZone.ts @@ -1,4 +1,19 @@ +import { useEffect, useState } from 'react'; + +type ServerInfo = { + transitTimeZone: string; +}; + +const fetchServerInfo = (): Promise => fetch('http://localhost:8080/otp/').then((r) => r.json()); + export const useTimeZone = () => { + const [data, setData] = useState(null); + useEffect(() => { + const fetchData = async () => { + setData(await fetchServerInfo()); + }; + fetchData(); + }, []); - return "America/Los_Angeles" + return data?.transitTimeZone || Intl.DateTimeFormat().resolvedOptions().timeZone; }; diff --git a/client/src/screens/App.tsx b/client/src/screens/App.tsx index 3e5744e5ad6..cb29654a4ff 100644 --- a/client/src/screens/App.tsx +++ b/client/src/screens/App.tsx @@ -6,39 +6,44 @@ import { useState } from 'react'; import { useTripQuery } from '../hooks/useTripQuery.ts'; import { useServerInfo } from '../hooks/useServerInfo.ts'; import { useTripQueryVariables } from '../hooks/useTripQueryVariables.ts'; +import { TimeZoneContext } from '../hooks/TimeZoneContext.ts'; +import { useTimeZone } from '../hooks/useTimeZone.ts'; export function App() { + const serverInfo = useServerInfo(); + const timeZone = useTimeZone(); const { tripQueryVariables, setTripQueryVariables } = useTripQueryVariables(); const [tripQueryResult, loading, callback] = useTripQuery(tripQueryVariables); - const serverInfo = useServerInfo(); const [selectedTripPatternIndex, setSelectedTripPatternIndex] = useState(0); return (
- - - - - + - + + + + + +
); } diff --git a/client/src/style.css b/client/src/style.css index 1a24ac2c072..76b431510ad 100644 --- a/client/src/style.css +++ b/client/src/style.css @@ -60,6 +60,12 @@ overflow-y: auto; } +.itinerary-list-container .time-zone-info{ + margin: 10px 20px; + font-size: 12px; + text-align: right; +} + .itinerary-header-wrapper { position: relative; background: #0a53be; diff --git a/client/src/util/formatTime.ts b/client/src/util/formatTime.ts index 1b14ab103c6..8068c0e29b0 100644 --- a/client/src/util/formatTime.ts +++ b/client/src/util/formatTime.ts @@ -1,16 +1,14 @@ -import {useTimeZone} from "../hooks/useTimeZone.ts"; - /** * Format departure and arrival times from scalar dateTime strings * * If style argument is provided formatted with ('medium') or without ('short') seconds, * otherwise seconds are shown if not 0. */ -export function formatTime(dateTime: string, style?: 'short' | 'medium') { +export function formatTime(dateTime: string, timeZone: string, style?: 'short' | 'medium') { const parsed = new Date(dateTime); return parsed.toLocaleTimeString('en-US', { timeStyle: style ? style : parsed.getSeconds() === 0 ? 'short' : 'medium', hourCycle: 'h24', - timeZone: useTimeZone() + timeZone: timeZone }); } From b55ecd7d86b93f6b370d4258a780fa5112cf64fd Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 23 Sep 2024 22:48:04 +0200 Subject: [PATCH 32/43] Remove memo of time --- .../components/SearchBar/DateTimeInputField.tsx | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/client/src/components/SearchBar/DateTimeInputField.tsx b/client/src/components/SearchBar/DateTimeInputField.tsx index c7e77ee8f05..b97ef1a35a7 100644 --- a/client/src/components/SearchBar/DateTimeInputField.tsx +++ b/client/src/components/SearchBar/DateTimeInputField.tsx @@ -1,6 +1,6 @@ import { Form } from 'react-bootstrap'; import { TripQueryVariables } from '../../gql/graphql.ts'; -import { ChangeEvent, useCallback, useContext, useMemo } from 'react'; +import { ChangeEvent, useCallback, useContext } from 'react'; import { Temporal } from '@js-temporal/polyfill'; import { TimeZoneContext } from '../../hooks/TimeZoneContext.ts'; @@ -12,14 +12,10 @@ export function DateTimeInputField({ setTripQueryVariables: (tripQueryVariables: TripQueryVariables) => void; }) { const timeZone = useContext(TimeZoneContext); - const current = useMemo( - () => - Temporal.Instant.from(tripQueryVariables.dateTime) - .toZonedDateTimeISO(timeZone) - .toPlainDateTime() - .toString({ smallestUnit: 'minute', calendarName: 'never' }), - [tripQueryVariables.dateTime], - ); + const current = Temporal.Instant.from(tripQueryVariables.dateTime) + .toZonedDateTimeISO(timeZone) + .toPlainDateTime() + .toString({ smallestUnit: 'minute', calendarName: 'never' }); const onChange = useCallback( (event: ChangeEvent) => { From eda11ecd9b289efd971c9befc365f173dda510cf Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Mon, 23 Sep 2024 23:25:44 +0200 Subject: [PATCH 33/43] Use configuration value for URL --- client/src/hooks/useTimeZone.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/src/hooks/useTimeZone.ts b/client/src/hooks/useTimeZone.ts index 36ab9d9d12a..7fa5fa9ba29 100644 --- a/client/src/hooks/useTimeZone.ts +++ b/client/src/hooks/useTimeZone.ts @@ -1,10 +1,12 @@ import { useEffect, useState } from 'react'; +const serverInfoUrl = import.meta.env.VITE_SERVER_INFO_URL; + type ServerInfo = { transitTimeZone: string; }; -const fetchServerInfo = (): Promise => fetch('http://localhost:8080/otp/').then((r) => r.json()); +const fetchServerInfo = (): Promise => fetch(serverInfoUrl).then((r) => r.json()); export const useTimeZone = () => { const [data, setData] = useState(null); From 208c8ad69dc9397b45acabf3328fad3086f3b75f Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 24 Sep 2024 10:27:39 +0200 Subject: [PATCH 34/43] Add comment --- client/src/hooks/useTimeZone.ts | 3 +++ client/src/style.css | 2 +- client/src/util/formatTime.ts | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/client/src/hooks/useTimeZone.ts b/client/src/hooks/useTimeZone.ts index 7fa5fa9ba29..4f568880e93 100644 --- a/client/src/hooks/useTimeZone.ts +++ b/client/src/hooks/useTimeZone.ts @@ -8,6 +8,9 @@ type ServerInfo = { const fetchServerInfo = (): Promise => fetch(serverInfoUrl).then((r) => r.json()); +/** + * Fetch the transit model's time zone from the server and use the browser's as the fallback. + */ export const useTimeZone = () => { const [data, setData] = useState(null); useEffect(() => { diff --git a/client/src/style.css b/client/src/style.css index 76b431510ad..37100d65006 100644 --- a/client/src/style.css +++ b/client/src/style.css @@ -60,7 +60,7 @@ overflow-y: auto; } -.itinerary-list-container .time-zone-info{ +.itinerary-list-container .time-zone-info { margin: 10px 20px; font-size: 12px; text-align: right; diff --git a/client/src/util/formatTime.ts b/client/src/util/formatTime.ts index 8068c0e29b0..1818ced5cd1 100644 --- a/client/src/util/formatTime.ts +++ b/client/src/util/formatTime.ts @@ -9,6 +9,6 @@ export function formatTime(dateTime: string, timeZone: string, style?: 'short' | return parsed.toLocaleTimeString('en-US', { timeStyle: style ? style : parsed.getSeconds() === 0 ? 'short' : 'medium', hourCycle: 'h24', - timeZone: timeZone + timeZone: timeZone, }); } From c09387b012cd8193b6995ecb2a7d97d200b1aa0e Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 24 Sep 2024 10:41:47 +0200 Subject: [PATCH 35/43] Fix linting issues --- .../components/ItineraryList/ItineraryHeaderContent.tsx | 4 ++-- client/src/components/SearchBar/DateTimeInputField.tsx | 2 +- .../api/model/serverinfo/ApiServerInfo.java | 7 ++++++- .../java/org/opentripplanner/api/resource/ServerInfo.java | 7 ++----- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/client/src/components/ItineraryList/ItineraryHeaderContent.tsx b/client/src/components/ItineraryList/ItineraryHeaderContent.tsx index 0788ca1974e..fdfea81e7e4 100644 --- a/client/src/components/ItineraryList/ItineraryHeaderContent.tsx +++ b/client/src/components/ItineraryList/ItineraryHeaderContent.tsx @@ -29,12 +29,12 @@ export function ItineraryHeaderContent({ const formattedStartTime = useMemo( () => formatTime(tripPattern.expectedStartTime, timeZone, 'short'), - [tripPattern.expectedStartTime], + [tripPattern.expectedStartTime, timeZone], ); const formattedEndTime = useMemo( () => formatTime(tripPattern.expectedEndTime, timeZone, 'short'), - [tripPattern.expectedEndTime], + [tripPattern.expectedEndTime, timeZone], ); return ( diff --git a/client/src/components/SearchBar/DateTimeInputField.tsx b/client/src/components/SearchBar/DateTimeInputField.tsx index b97ef1a35a7..492f32912ab 100644 --- a/client/src/components/SearchBar/DateTimeInputField.tsx +++ b/client/src/components/SearchBar/DateTimeInputField.tsx @@ -28,7 +28,7 @@ export function DateTimeInputField({ dateTime: dateTime, }); }, - [tripQueryVariables, setTripQueryVariables], + [tripQueryVariables, setTripQueryVariables, timeZone], ); return ( diff --git a/src/main/java/org/opentripplanner/api/model/serverinfo/ApiServerInfo.java b/src/main/java/org/opentripplanner/api/model/serverinfo/ApiServerInfo.java index e4b42d48e59..bf8a09dea3e 100644 --- a/src/main/java/org/opentripplanner/api/model/serverinfo/ApiServerInfo.java +++ b/src/main/java/org/opentripplanner/api/model/serverinfo/ApiServerInfo.java @@ -13,7 +13,12 @@ public class ApiServerInfo { public final String otpSerializationVersionId; public final String transitTimeZone; - public ApiServerInfo(String cpuName, int nCores, OtpProjectInfo projectInfo, ZoneId transitTimeZone) { + public ApiServerInfo( + String cpuName, + int nCores, + OtpProjectInfo projectInfo, + ZoneId transitTimeZone + ) { this.cpuName = cpuName; this.nCores = nCores; this.version = new ApiProjectVersion(projectInfo.version); diff --git a/src/main/java/org/opentripplanner/api/resource/ServerInfo.java b/src/main/java/org/opentripplanner/api/resource/ServerInfo.java index c11d9c8158f..ef94f970280 100644 --- a/src/main/java/org/opentripplanner/api/resource/ServerInfo.java +++ b/src/main/java/org/opentripplanner/api/resource/ServerInfo.java @@ -20,13 +20,12 @@ public class ServerInfo { private final ZoneId timeZone; private static final String cpuName; - private static final int nCores ; + private static final int nCores; public ServerInfo(@Context OtpServerRequestContext serverContext) { this.timeZone = serverContext.transitService().getTimeZone(); } - /** * Determine the OTP version and CPU type of the running server. This information should not * change while the server is up, so it can safely be cached at startup. The project info is not @@ -43,7 +42,7 @@ public ServerInfo(@Context OtpServerRequestContext serverContext) { while ((line = br.readLine()) != null) { if (line.startsWith("model name")) { cpu = line.split(": ")[1]; - cores+= 1; + cores += 1; } } fis.close(); @@ -52,8 +51,6 @@ public ServerInfo(@Context OtpServerRequestContext serverContext) { nCores = cores; } - - @GET @Produces(MediaType.APPLICATION_JSON) public ApiServerInfo getServerInfo() { From 0be72d37d05f41e56da738711d70e31b62d87cf7 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 24 Sep 2024 12:04:36 +0200 Subject: [PATCH 36/43] Add internal time zone to Transmodel GraphQL API --- client/src/hooks/useServerInfo.ts | 1 + client/src/hooks/useTimeZone.ts | 24 ----------------- client/src/screens/App.tsx | 3 +-- .../api/model/serverinfo/ApiServerInfo.java | 10 +------ .../api/resource/ServerInfo.java | 27 +++++++------------ .../transmodel/TransmodelGraphQLSchema.java | 4 ++- .../model/framework/ServerInfoType.java | 23 ++++++++++++++++ .../apis/transmodel/schema.graphql | 6 +++++ 8 files changed, 44 insertions(+), 54 deletions(-) delete mode 100644 client/src/hooks/useTimeZone.ts diff --git a/client/src/hooks/useServerInfo.ts b/client/src/hooks/useServerInfo.ts index 23ee23fc283..117c1357360 100644 --- a/client/src/hooks/useServerInfo.ts +++ b/client/src/hooks/useServerInfo.ts @@ -13,6 +13,7 @@ const query = graphql(` routerConfigVersion gitCommit gitBranch + internalTransitModelTimeZone } } `); diff --git a/client/src/hooks/useTimeZone.ts b/client/src/hooks/useTimeZone.ts deleted file mode 100644 index 4f568880e93..00000000000 --- a/client/src/hooks/useTimeZone.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { useEffect, useState } from 'react'; - -const serverInfoUrl = import.meta.env.VITE_SERVER_INFO_URL; - -type ServerInfo = { - transitTimeZone: string; -}; - -const fetchServerInfo = (): Promise => fetch(serverInfoUrl).then((r) => r.json()); - -/** - * Fetch the transit model's time zone from the server and use the browser's as the fallback. - */ -export const useTimeZone = () => { - const [data, setData] = useState(null); - useEffect(() => { - const fetchData = async () => { - setData(await fetchServerInfo()); - }; - fetchData(); - }, []); - - return data?.transitTimeZone || Intl.DateTimeFormat().resolvedOptions().timeZone; -}; diff --git a/client/src/screens/App.tsx b/client/src/screens/App.tsx index cb29654a4ff..1b6b86b7a81 100644 --- a/client/src/screens/App.tsx +++ b/client/src/screens/App.tsx @@ -7,14 +7,13 @@ import { useTripQuery } from '../hooks/useTripQuery.ts'; import { useServerInfo } from '../hooks/useServerInfo.ts'; import { useTripQueryVariables } from '../hooks/useTripQueryVariables.ts'; import { TimeZoneContext } from '../hooks/TimeZoneContext.ts'; -import { useTimeZone } from '../hooks/useTimeZone.ts'; export function App() { const serverInfo = useServerInfo(); - const timeZone = useTimeZone(); const { tripQueryVariables, setTripQueryVariables } = useTripQueryVariables(); const [tripQueryResult, loading, callback] = useTripQuery(tripQueryVariables); const [selectedTripPatternIndex, setSelectedTripPatternIndex] = useState(0); + const timeZone = serverInfo?.internalTransitModelTimeZone || Intl.DateTimeFormat().resolvedOptions().timeZone; return (
diff --git a/src/main/java/org/opentripplanner/api/model/serverinfo/ApiServerInfo.java b/src/main/java/org/opentripplanner/api/model/serverinfo/ApiServerInfo.java index bf8a09dea3e..e90c0e37fdf 100644 --- a/src/main/java/org/opentripplanner/api/model/serverinfo/ApiServerInfo.java +++ b/src/main/java/org/opentripplanner/api/model/serverinfo/ApiServerInfo.java @@ -1,6 +1,5 @@ package org.opentripplanner.api.model.serverinfo; -import java.time.ZoneId; import org.opentripplanner.model.projectinfo.OtpProjectInfo; public class ApiServerInfo { @@ -11,20 +10,13 @@ public class ApiServerInfo { public final ApiVersionControlInfo versionControl; public final ApiConfigInfo config; public final String otpSerializationVersionId; - public final String transitTimeZone; - public ApiServerInfo( - String cpuName, - int nCores, - OtpProjectInfo projectInfo, - ZoneId transitTimeZone - ) { + public ApiServerInfo(String cpuName, int nCores, OtpProjectInfo projectInfo) { this.cpuName = cpuName; this.nCores = nCores; this.version = new ApiProjectVersion(projectInfo.version); this.versionControl = new ApiVersionControlInfo(projectInfo.versionControl); this.config = new ApiConfigInfo(projectInfo); this.otpSerializationVersionId = projectInfo.getOtpSerializationVersionId(); - this.transitTimeZone = transitTimeZone.toString(); } } diff --git a/src/main/java/org/opentripplanner/api/resource/ServerInfo.java b/src/main/java/org/opentripplanner/api/resource/ServerInfo.java index ef94f970280..bc8d91d4780 100644 --- a/src/main/java/org/opentripplanner/api/resource/ServerInfo.java +++ b/src/main/java/org/opentripplanner/api/resource/ServerInfo.java @@ -3,28 +3,19 @@ import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.Context; import jakarta.ws.rs.core.MediaType; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; -import java.time.ZoneId; import org.opentripplanner.api.model.serverinfo.ApiServerInfo; import org.opentripplanner.model.projectinfo.OtpProjectInfo; -import org.opentripplanner.standalone.api.OtpServerRequestContext; @Path("/") public class ServerInfo { - private final ZoneId timeZone; - private static final String cpuName; - private static final int nCores; - - public ServerInfo(@Context OtpServerRequestContext serverContext) { - this.timeZone = serverContext.transitService().getTimeZone(); - } + private static final ApiServerInfo SERVER_INFO = createServerInfo(); /** * Determine the OTP version and CPU type of the running server. This information should not @@ -32,28 +23,28 @@ public ServerInfo(@Context OtpServerRequestContext serverContext) { * available before the graph is loaded, so for this to work this class should not be loaded * BEFORE that. */ - static { - var cpu = "unknown"; - int cores = 0; + public static ApiServerInfo createServerInfo() { + String cpuName = "unknown"; + int nCores = 0; try { InputStream fis = new FileInputStream("/proc/cpuinfo"); BufferedReader br = new BufferedReader(new InputStreamReader(fis, StandardCharsets.UTF_8)); String line; while ((line = br.readLine()) != null) { if (line.startsWith("model name")) { - cpu = line.split(": ")[1]; - cores += 1; + cpuName = line.split(": ")[1]; + nCores += 1; } } fis.close(); } catch (Exception ignore) {} - cpuName = cpu; - nCores = cores; + + return new ApiServerInfo(cpuName, nCores, OtpProjectInfo.projectInfo()); } @GET @Produces(MediaType.APPLICATION_JSON) public ApiServerInfo getServerInfo() { - return new ApiServerInfo(cpuName, nCores, OtpProjectInfo.projectInfo(), timeZone); + return SERVER_INFO; } } diff --git a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchema.java b/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchema.java index 9ad43606420..b5a934722ea 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchema.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/TransmodelGraphQLSchema.java @@ -1623,7 +1623,9 @@ private GraphQLSchema create() { GraphQLFieldDefinition .newFieldDefinition() .name("serverInfo") - .description("Get OTP server information") + .description( + "Get OTP deployment information. This is only useful for developers of OTP itself not regular API users." + ) .withDirective(gqlUtil.timingData) .type(new GraphQLNonNull(serverInfoType)) .dataFetcher(e -> projectInfo()) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ServerInfoType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ServerInfoType.java index ae6889ab033..98cd8be5bf4 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ServerInfoType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ServerInfoType.java @@ -9,6 +9,7 @@ import graphql.schema.GraphQLFieldDefinition; import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLOutputType; +import org.opentripplanner.apis.transmodel.support.GqlUtil; public class ServerInfoType { @@ -16,6 +17,13 @@ public static GraphQLOutputType create() { return GraphQLObjectType .newObject() .name("ServerInfo") + .description( + """ + Information about the deployment. This is only useful to developers of OTP itself. + It is not recommended for regular API consumers to use this type as it has no + stability guarantees. + """ + ) .field( GraphQLFieldDefinition .newFieldDefinition() @@ -99,6 +107,21 @@ public static GraphQLOutputType create() { .dataFetcher(e -> projectInfo().getOtpSerializationVersionId()) .build() ) + .field( + GraphQLFieldDefinition + .newFieldDefinition() + .name("internalTransitModelTimeZone") + .description( + """ + The internal time zone of the transit data. + + Note: Input data can be in several time zones but OTP internally operates on a single one. + """ + ) + .type(Scalars.GraphQLString) + .dataFetcher(e -> GqlUtil.getTransitService(e).getTimeZone()) + .build() + ) .build(); } } diff --git a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql index 0d2bf71dcc6..7ced7680a47 100644 --- a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql +++ b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql @@ -1075,6 +1075,12 @@ type ServerInfo { gitBranch: String gitCommit: String gitCommitTime: String + """ + The internal time zone of the transit data. + + Note: Input data can be in several time zones but OTP internally operates on a single one. + """ + internalTransitModelTimeZone: String "The 'configVersion' of the otp-config.json file." otpConfigVersion: String "The otp-serialization-version-id used to check graphs for compatibility with current version of OTP." From e9c029f01b1e76e24c899057fedee157e1bf343e Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 24 Sep 2024 12:48:38 +0200 Subject: [PATCH 37/43] Update schema docs --- .../org/opentripplanner/apis/transmodel/schema.graphql | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql index 7ced7680a47..9282ece1255 100644 --- a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql +++ b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql @@ -730,7 +730,7 @@ type QueryType { ): quayAtDistanceConnection @timingData "Get default routing parameters." routingParameters: RoutingParameters @timingData - "Get OTP server information" + "Get OTP deployment information. This is only useful for developers of OTP itself not regular API users." serverInfo: ServerInfo! @timingData "Get a single service journey based on its id" serviceJourney(id: String!): ServiceJourney @timingData @@ -1067,6 +1067,11 @@ type RoutingParameters { wheelChairAccessible: Boolean } +""" +Information about the deployment. This is only useful to developers of OTP itself. +It is not recommended for regular API consumers to use this type as it has no +stability guarantees. +""" type ServerInfo { "The 'configVersion' of the build-config.json file." buildConfigVersion: String From 769bb508f82fc598a2eb05a6e88ef4a800ac3520 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 24 Sep 2024 13:40:28 +0200 Subject: [PATCH 38/43] Remove unused env variables --- client/.env | 1 - client/.env.development | 1 - 2 files changed, 2 deletions(-) diff --git a/client/.env b/client/.env index a4fbf511e26..2f5d271b1e4 100644 --- a/client/.env +++ b/client/.env @@ -1,4 +1,3 @@ VITE_API_URL=/otp/transmodel/v3 VITE_DEBUG_STYLE_URL=/otp/routers/default/inspector/vectortile/style.json VITE_GRAPHIQL_URL=/graphiql?flavor=transmodel -VITE_SERVER_INFO_URL=/otp/ diff --git a/client/.env.development b/client/.env.development index 70ad81eb7dd..e3b3585a5eb 100644 --- a/client/.env.development +++ b/client/.env.development @@ -1,4 +1,3 @@ VITE_API_URL=http://localhost:8080/otp/transmodel/v3 VITE_DEBUG_STYLE_URL=http://localhost:8080/otp/routers/default/inspector/vectortile/style.json VITE_GRAPHIQL_URL=http://localhost:8080/graphiql?flavor=transmodel -VITE_SERVER_INFO_URL=http://localhost:8080/otp/ From e577006481abba7f947f0b656b5ce5f172231d6e Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 24 Sep 2024 13:46:33 +0200 Subject: [PATCH 39/43] Update schema docs Co-authored-by: Thomas Gran --- .../org/opentripplanner/apis/transmodel/schema.graphql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql index 9282ece1255..b53741fa828 100644 --- a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql +++ b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql @@ -1083,7 +1083,7 @@ type ServerInfo { """ The internal time zone of the transit data. - Note: Input data can be in several time zones but OTP internally operates on a single one. + Note: The input data can be in several time zones, but OTP internally operates on a single one. """ internalTransitModelTimeZone: String "The 'configVersion' of the otp-config.json file." From b5d7e13c3a3a0ed41ea43947af44322e10e191ad Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 24 Sep 2024 13:49:11 +0200 Subject: [PATCH 40/43] Update schema docs --- .../org/opentripplanner/apis/transmodel/schema.graphql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql index b53741fa828..9282ece1255 100644 --- a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql +++ b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql @@ -1083,7 +1083,7 @@ type ServerInfo { """ The internal time zone of the transit data. - Note: The input data can be in several time zones, but OTP internally operates on a single one. + Note: Input data can be in several time zones but OTP internally operates on a single one. """ internalTransitModelTimeZone: String "The 'configVersion' of the otp-config.json file." From 7080ebb0822e29e39e585686d97593129610acef Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Tue, 24 Sep 2024 13:56:08 +0200 Subject: [PATCH 41/43] Update src/main/java/org/opentripplanner/apis/transmodel/model/framework/ServerInfoType.java --- .../apis/transmodel/model/framework/ServerInfoType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ServerInfoType.java b/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ServerInfoType.java index 98cd8be5bf4..8f679cafda3 100644 --- a/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ServerInfoType.java +++ b/src/main/java/org/opentripplanner/apis/transmodel/model/framework/ServerInfoType.java @@ -115,7 +115,7 @@ public static GraphQLOutputType create() { """ The internal time zone of the transit data. - Note: Input data can be in several time zones but OTP internally operates on a single one. + Note: The input data can be in several time zones, but OTP internally operates on a single one. """ ) .type(Scalars.GraphQLString) From 60b738351a59bf9adb1b6530bbdcb41338ebb554 Mon Sep 17 00:00:00 2001 From: Thomas Gran Date: Tue, 24 Sep 2024 13:57:12 +0200 Subject: [PATCH 42/43] Update src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql --- .../org/opentripplanner/apis/transmodel/schema.graphql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql index 9282ece1255..b53741fa828 100644 --- a/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql +++ b/src/main/resources/org/opentripplanner/apis/transmodel/schema.graphql @@ -1083,7 +1083,7 @@ type ServerInfo { """ The internal time zone of the transit data. - Note: Input data can be in several time zones but OTP internally operates on a single one. + Note: The input data can be in several time zones, but OTP internally operates on a single one. """ internalTransitModelTimeZone: String "The 'configVersion' of the otp-config.json file." From 9c10a0eff2e2f72920f6c811d8c2274163e17afe Mon Sep 17 00:00:00 2001 From: OTP Bot Date: Tue, 24 Sep 2024 12:05:43 +0000 Subject: [PATCH 43/43] Upgrade debug client to version 2024/09/2024-09-24T12:05 --- src/client/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/index.html b/src/client/index.html index 5b3dd90b341..6a7d7f32aaa 100644 --- a/src/client/index.html +++ b/src/client/index.html @@ -5,8 +5,8 @@ OTP Debug Client - - + +