Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
28eacb5
Encapsulate date and timezone in RealtimeTestEnvironment
habrahamsson-skanetrafiken Sep 24, 2025
06a880a
Extract siri logic from RealtimeTestEnvironment
habrahamsson-skanetrafiken Sep 24, 2025
14e590e
Extract gtfs-rt logic from RealtimeTestEnvironment
habrahamsson-skanetrafiken Sep 24, 2025
7ac134f
Rename RealtimeTestEnvironment to TransitTestEnvironment
habrahamsson-skanetrafiken Sep 24, 2025
7611c2e
Merge branch 'dev-2.x' into test-encapsulate-service-date
habrahamsson-skanetrafiken Oct 1, 2025
de5ca5b
Fixes after merge
habrahamsson-skanetrafiken Oct 1, 2025
0ab336e
Address review comment
habrahamsson-skanetrafiken Oct 2, 2025
991bf27
Add TripOnDateDataFetcher
habrahamsson-skanetrafiken Oct 2, 2025
8774d9e
Fix ReplacementTest
habrahamsson-skanetrafiken Oct 2, 2025
220094d
Rename DateTimeHelper -> LocalTimeParser
habrahamsson-skanetrafiken Oct 6, 2025
888d28a
Remove unused code
habrahamsson-skanetrafiken Oct 6, 2025
28efac9
Rename a method
habrahamsson-skanetrafiken Oct 6, 2025
2724f6b
Make a separate builder for SiteRepository
habrahamsson-skanetrafiken Oct 6, 2025
b1cbb26
Don't take siterepo as parameter
habrahamsson-skanetrafiken Oct 8, 2025
7045171
Separate the timetable building logic into its own class
habrahamsson-skanetrafiken Oct 8, 2025
d4c0fdb
Don't create tripOnServiceDate by default
habrahamsson-skanetrafiken Oct 8, 2025
47f106f
Simplify calendar stuff
habrahamsson-skanetrafiken Oct 8, 2025
7c96ccd
Explicit route handling
habrahamsson-skanetrafiken Oct 8, 2025
45f14bb
Simplify trip creation
habrahamsson-skanetrafiken Oct 8, 2025
5ea2ff6
Simplify trip creation
habrahamsson-skanetrafiken Oct 8, 2025
626b39c
Move feed id generation to its own class
habrahamsson-skanetrafiken Oct 8, 2025
d9fc270
Add some documentation
habrahamsson-skanetrafiken Oct 9, 2025
7ca4f2a
Remove some dependencies on RealtimeTestConstants
habrahamsson-skanetrafiken Oct 9, 2025
05d8aca
Fix some code style
habrahamsson-skanetrafiken Oct 9, 2025
77e37b5
Rename tripFetcher method
habrahamsson-skanetrafiken Oct 9, 2025
4513b0e
Fix some doc
habrahamsson-skanetrafiken Oct 9, 2025
6709785
Add deprecation
habrahamsson-skanetrafiken Oct 9, 2025
3b4653d
Minor fixes
habrahamsson-skanetrafiken Oct 9, 2025
512ae45
Add constants for trip ids
habrahamsson-skanetrafiken Oct 10, 2025
a652dd3
Fix naming issues
habrahamsson-skanetrafiken Oct 10, 2025
063c8ac
Use default service date in cancellationtest
habrahamsson-skanetrafiken Oct 10, 2025
851d92a
Fix more naming
habrahamsson-skanetrafiken Oct 10, 2025
1130f55
Expose builders in TransitTestEnvironmentBuilder
habrahamsson-skanetrafiken Oct 13, 2025
909a206
Unify flex and regular trip creation
habrahamsson-skanetrafiken Oct 13, 2025
0cbe02c
Address review comment
habrahamsson-skanetrafiken Oct 14, 2025
9bd7180
Rename private class StopCall -> StopCallInput
habrahamsson-skanetrafiken Oct 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id;

import java.time.Duration;
import java.time.Instant;
import java.time.LocalTime;
import java.util.List;
import java.util.Set;
import org.junit.jupiter.api.Test;
Expand All @@ -21,21 +19,24 @@
import org.opentripplanner.routing.graphfinder.PlaceAtDistance;
import org.opentripplanner.routing.graphfinder.PlaceType;
import org.opentripplanner.street.search.state.TestStateBuilder;
import org.opentripplanner.transit.model._data.TransitTestEnvironment;
import org.opentripplanner.transit.model._data.TransitTestEnvironmentBuilder;
import org.opentripplanner.transit.model._data.TripInput;
import org.opentripplanner.transit.model.basic.TransitMode;
import org.opentripplanner.transit.model.framework.EntityNotFoundException;
import org.opentripplanner.transit.model.framework.FeedScopedId;
import org.opentripplanner.transit.model.site.RegularStop;
import org.opentripplanner.transit.service.ArrivalDeparture;
import org.opentripplanner.transit.service.TransitService;
import org.opentripplanner.updater.trip.RealtimeTestConstants;
import org.opentripplanner.updater.trip.RealtimeTestEnvironment;
import org.opentripplanner.updater.trip.RealtimeTestEnvironmentBuilder;
import org.opentripplanner.updater.trip.TripInput;
import org.opentripplanner.utils.time.TimeUtils;

class OjpServiceTest implements RealtimeTestConstants {
class OjpServiceTest {

private final RealtimeTestEnvironmentBuilder envBuilder = RealtimeTestEnvironment.of();
private final TransitTestEnvironmentBuilder envBuilder = TransitTestEnvironment.of();

private static final String STOP_A_ID = "A";
private static final String STOP_B_ID = "B";
private static final String STOP_C_ID = "C";
private static final String STATION_OMEGA_ID = "OMEGA";

private final RegularStop STOP_A = envBuilder.stopAtStation(STOP_A_ID, STATION_OMEGA_ID);
private final RegularStop STOP_B = envBuilder.stop(STOP_B_ID);
Expand All @@ -44,14 +45,11 @@ class OjpServiceTest implements RealtimeTestConstants {
private final TripInput TRIP_INPUT = TripInput.of("t1")
.addStop(STOP_A, "12:00", "12:01")
.addStop(STOP_B, "12:10", "12:11")
.addStop(STOP_C, "12:20", "12:21")
.build();

public static final OjpService.StopEventRequestParams PARAMS = params(100);
.addStop(STOP_C, "12:20", "12:21");

private static OjpService.StopEventRequestParams params(int departures) {
private OjpService.StopEventRequestParams params(TransitTestEnvironment env, int departures) {
return new OjpService.StopEventRequestParams(
instant("12:00"),
env.localTimeParser().instant("12:00"),
ArrivalDeparture.BOTH,
Duration.ofHours(2),
1000,
Expand All @@ -73,8 +71,8 @@ public static List<FeedScopedId> stopPointRefCases() {
@MethodSource("stopPointRefCases")
void stopPointRef(FeedScopedId ref) {
var env = envBuilder.addTrip(TRIP_INPUT).build();
var service = new OjpService(env.getTransitService(), new DirectGraphFinder(e -> List.of()));
var result = service.findCallsAtStop(ref, PARAMS);
var service = new OjpService(env.transitService(), new DirectGraphFinder(e -> List.of()));
var result = service.findCallsAtStop(ref, params(env, 100));
assertThat(result).hasSize(1);
var stopId = result.getFirst().tripTimeOnDate().getStop().getId();
assertEquals(STOP_A.getId(), stopId);
Expand All @@ -83,9 +81,9 @@ void stopPointRef(FeedScopedId ref) {
@Test
void notFound() {
var env = envBuilder.addTrip(TRIP_INPUT).build();
var service = new OjpService(env.getTransitService(), new DirectGraphFinder(e -> List.of()));
var service = new OjpService(env.transitService(), new DirectGraphFinder(e -> List.of()));
assertThrows(EntityNotFoundException.class, () ->
service.findCallsAtStop(id("unknown"), PARAMS)
service.findCallsAtStop(id("unknown"), params(env, 100))
);
}

Expand Down Expand Up @@ -118,8 +116,8 @@ public List<PlaceAtDistance> findClosestPlaces(
}
};
var env = envBuilder.addTrip(TRIP_INPUT).build();
var service = new OjpService(env.getTransitService(), finder);
var result = service.findCallsAtStop(WgsCoordinate.GREENWICH, PARAMS);
var service = new OjpService(env.transitService(), finder);
var result = service.findCallsAtStop(WgsCoordinate.GREENWICH, params(env, 100));
assertThat(result).hasSize(1);
var stopId = result.getFirst().tripTimeOnDate().getStop().getId();
assertEquals(STOP_A.getId(), stopId);
Expand All @@ -128,14 +126,9 @@ public List<PlaceAtDistance> findClosestPlaces(
@Test
void tooManyDepartures() {
var env = envBuilder.addTrip(TRIP_INPUT).build();
var service = new OjpService(env.getTransitService(), new DirectGraphFinder(e -> List.of()));
var service = new OjpService(env.transitService(), new DirectGraphFinder(e -> List.of()));
assertThrows(IllegalArgumentException.class, () ->
service.findCallsAtStop(STOP_A.getId(), params(101))
service.findCallsAtStop(STOP_A.getId(), params(env, 101))
);
}

private static Instant instant(String time) {
var localTime = LocalTime.ofSecondOfDay(TimeUtils.time(time));
return localTime.atDate(SERVICE_DATE).atZone(TIME_ZONE).toInstant();
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
package org.opentripplanner;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import org.opentripplanner.utils.time.DateUtils;
import org.opentripplanner.utils.time.TimeUtils;

public class DateTimeHelper {
/**
* A helper class used in tests for parsing local time strings into absolute times given a date and
* a timezone.
*/
public class LocalTimeParser {

private final ZoneId zone;
private final LocalDate defaultDate;

public DateTimeHelper(ZoneId zone, LocalDate defaultDate) {
public LocalTimeParser(ZoneId zone, LocalDate defaultDate) {
this.zone = zone;
this.defaultDate = defaultDate;
}
Expand All @@ -27,4 +34,13 @@ public ZonedDateTime zonedDateTime(String timeString) {
}
return defaultDate.atTime(time).atZone(zone);
}

/**
* Takes local time on different formats like "12:34:00" or "12:34" and returns the corresponding
* instant at the given date on the specific timezone.
*/
public Instant instant(String timeString) {
var localTime = LocalTime.ofSecondOfDay(TimeUtils.time(timeString));
return localTime.atDate(defaultDate).atZone(zone).toInstant();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,62 +3,66 @@
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Instant;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.opentripplanner.apis.gtfs.model.CallSchedule;
import org.opentripplanner.apis.gtfs.model.CallScheduledTime.ArrivalDepartureTime;
import org.opentripplanner.apis.gtfs.model.CallScheduledTime.TimeWindow;
import org.opentripplanner.framework.application.OTPFeature;
import org.opentripplanner.model.TripTimeOnDate;
import org.opentripplanner.transit.model._data.TransitTestEnvironment;
import org.opentripplanner.transit.model._data.TransitTestEnvironmentBuilder;
import org.opentripplanner.transit.model._data.TripInput;
import org.opentripplanner.transit.model.site.AreaStop;
import org.opentripplanner.transit.model.site.RegularStop;
import org.opentripplanner.updater.trip.FlexTripInput;
import org.opentripplanner.updater.trip.RealtimeTestConstants;
import org.opentripplanner.updater.trip.RealtimeTestEnvironment;
import org.opentripplanner.updater.trip.RealtimeTestEnvironmentBuilder;
import org.opentripplanner.updater.trip.TripInput;
import org.opentripplanner.utils.time.ServiceDateUtils;

class StopCallImplTest implements RealtimeTestConstants {
class StopCallImplTest {

private static final LocalDate SERVICE_DATE = LocalDate.of(2023, 6, 3);
private static final ZoneId TIME_ZONE = ZoneId.of("Europe/Paris");
private static final Instant MIDNIGHT = ServiceDateUtils.asStartOfService(
SERVICE_DATE,
TIME_ZONE
).toInstant();
private static final OffsetDateTime NOON = OffsetDateTime.parse("2024-05-08T12:00+02:00");
private static final String TRIP_ID = "Trip1";
private static final String FLEX_TRIP_ID = "FlexTrip1";

private static final OffsetDateTime NOON = OffsetDateTime.parse("2023-06-03T12:00+02:00");
private static final OffsetDateTime TEN_AM = NOON.minusHours(2);
private final RealtimeTestEnvironmentBuilder envBuilder = RealtimeTestEnvironment.of();
private final RegularStop STOP_A = envBuilder.stop(STOP_A_ID);
private final RegularStop STOP_B = envBuilder.stop(STOP_B_ID);
private final RegularStop STOP_C = envBuilder.stop(STOP_C_ID);
private final AreaStop STOP_D = envBuilder.areaStop(STOP_D_ID);
private final AreaStop STOP_E = envBuilder.areaStop(STOP_E_ID);
private final TransitTestEnvironmentBuilder envBuilder = TransitTestEnvironment.of(SERVICE_DATE);
private final RegularStop STOP_A = envBuilder.stop("A");
private final RegularStop STOP_B = envBuilder.stop("B");
private final RegularStop STOP_C = envBuilder.stop("C");
private final AreaStop STOP_D = envBuilder.areaStop("D");
private final AreaStop STOP_E = envBuilder.areaStop("E");

private final TripInput TRIP_INPUT = TripInput.of(TRIP_1_ID)
private final TripInput TRIP_INPUT = TripInput.of(TRIP_ID)
.addStop(STOP_A, "12:00:00", "12:00:00")
.addStop(STOP_B, "12:30:00", "12:30:00")
.addStop(STOP_C, "13:00:00", "13:00:00")
.build();
.addStop(STOP_C, "13:00:00", "13:00:00");

private final FlexTripInput FLEX_TRIP_INPUT = FlexTripInput.of(TRIP_1_ID)
private final TripInput FLEX_TRIP_INPUT = TripInput.flex(FLEX_TRIP_ID)
.addStop(STOP_D, "10:00", "10:30")
.addStop(STOP_E, "11:00", "11:30")
.build();
.addStop(STOP_E, "11:00", "11:30");

@Test
void fixedTrip() throws Exception {
var realtimeEnv = envBuilder.addTrip(TRIP_INPUT).build();
var tripTimes = realtimeEnv.getTripTimesForTrip(TRIP_1_ID);
var pattern = realtimeEnv.getPatternForTrip(TRIP_1_ID);
var tripData = realtimeEnv.tripData(TRIP_ID);
var tripTimes = tripData.tripTimes();
var pattern = tripData.tripPattern();

var call = new TripTimeOnDate(tripTimes, 0, pattern, SERVICE_DATE, MIDNIGHT);

var impl = new StopCallImpl();
var env = DataFetchingSupport.dataFetchingEnvironment(
call,
Map.of(),
realtimeEnv.getTransitService()
realtimeEnv.transitService()
);

var schedule = impl.schedule().get(env);
Expand All @@ -68,17 +72,18 @@ void fixedTrip() throws Exception {
@Test
void flexTrip() {
OTPFeature.FlexRouting.testOn(() -> {
var realtimeEnv = envBuilder.addFlexTrip(FLEX_TRIP_INPUT).build();
var tripTimes = realtimeEnv.getTripTimesForTrip(TRIP_1_ID);
var pattern = realtimeEnv.getPatternForTrip(TRIP_1_ID);
var realtimeEnv = envBuilder.addTrip(FLEX_TRIP_INPUT).build();
var tripData = realtimeEnv.tripData(FLEX_TRIP_ID);
var tripTimes = tripData.tripTimes();
var pattern = tripData.tripPattern();

var call = new TripTimeOnDate(tripTimes, 0, pattern, SERVICE_DATE, MIDNIGHT);

var impl = new StopCallImpl();
var env = DataFetchingSupport.dataFetchingEnvironment(
call,
Map.of(),
realtimeEnv.getTransitService()
realtimeEnv.transitService()
);

// using try-catch is not very nice here - ideally we would just add it to the method signature.
Expand Down
Loading
Loading