diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java index 696febfef8b..5e2fd9ff994 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/RaptorPathToItineraryMapper.java @@ -10,6 +10,7 @@ import org.opentripplanner.framework.application.OTPFeature; import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.framework.i18n.NonLocalizedString; +import org.opentripplanner.framework.model.TimeAndCost; import org.opentripplanner.model.GenericLocation; import org.opentripplanner.model.plan.FrequencyTransitLegBuilder; import org.opentripplanner.model.plan.Itinerary; @@ -20,6 +21,7 @@ import org.opentripplanner.model.plan.StreetLeg; import org.opentripplanner.model.plan.UnknownTransitPathLeg; import org.opentripplanner.model.transfer.ConstrainedTransfer; +import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.path.AccessPathLeg; import org.opentripplanner.raptor.api.path.EgressPathLeg; import org.opentripplanner.raptor.api.path.PathLeg; @@ -156,15 +158,15 @@ else if (pathLeg.isTransferLeg()) { } var penaltyCost = 0; - if (accessPathLeg.access() instanceof RoutingAccessEgress ae) { - itinerary.setAccessPenalty(ae.penalty()); - penaltyCost += ae.penalty().cost().toSeconds(); - } - if (egressPathLeg.egress() instanceof RoutingAccessEgress ae) { - itinerary.setEgressPenalty(ae.penalty()); - penaltyCost += ae.penalty().cost().toSeconds(); - } + var accessPenalty = mapAccessEgressPenalty(accessPathLeg.access()); + itinerary.setAccessPenalty(accessPenalty); + penaltyCost += accessPenalty.cost().toSeconds(); + + var egressPenalty = mapAccessEgressPenalty(egressPathLeg.egress()); + itinerary.setEgressPenalty(egressPenalty); + penaltyCost += egressPenalty.cost().toSeconds(); + if (path.isC2Set()) { itinerary.setGeneralizedCost2(path.c2()); } @@ -192,11 +194,7 @@ private List mapAccessLeg(AccessPathLeg accessPathLeg) { return List.of(); } - RoutingAccessEgress accessPath = (RoutingAccessEgress) accessPathLeg.access(); - - var graphPath = new GraphPath<>(accessPath.getLastState()); - - Itinerary subItinerary = graphPathToItineraryMapper.generateItinerary(graphPath); + var subItinerary = mapAccessEgressPathLeg(accessPathLeg.access()); if (subItinerary.getLegs().isEmpty()) { return List.of(); @@ -329,11 +327,7 @@ private Itinerary mapEgressLeg(EgressPathLeg egressPathLeg) { return null; } - RoutingAccessEgress egressPath = (RoutingAccessEgress) egressPathLeg.egress(); - - var graphPath = new GraphPath<>(egressPath.getLastState()); - - Itinerary subItinerary = graphPathToItineraryMapper.generateItinerary(graphPath); + var subItinerary = mapAccessEgressPathLeg(egressPathLeg.egress()); if (subItinerary.getLegs().isEmpty()) { return null; @@ -432,4 +426,20 @@ private boolean includeTransferInItinerary(Leg transitLegBeforeTransfer) { !transitLegBeforeTransfer.getTransferToNextLeg().getTransferConstraint().isStaySeated() ); } + + private Itinerary mapAccessEgressPathLeg(RaptorAccessEgress accessEgress) { + return accessEgress + .findOriginal(RoutingAccessEgress.class) + .map(RoutingAccessEgress::getLastState) + .map(GraphPath::new) + .map(graphPathToItineraryMapper::generateItinerary) + .orElseThrow(); + } + + private TimeAndCost mapAccessEgressPenalty(RaptorAccessEgress accessEgress) { + return accessEgress + .findOriginal(RoutingAccessEgress.class) + .map(RoutingAccessEgress::penalty) + .orElseThrow(); + } } diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultAccessEgress.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultAccessEgress.java index 584e690d3ee..564603a1f61 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultAccessEgress.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultAccessEgress.java @@ -24,28 +24,48 @@ public class DefaultAccessEgress implements RoutingAccessEgress { */ private final State lastState; - public DefaultAccessEgress(int stop, State lastState) { + /** + * This is public to allow unit-tests full control over the field values. + */ + public DefaultAccessEgress( + int stop, + int durationInSeconds, + int generalizedCost, + TimeAndCost penalty, + State lastState + ) { this.stop = stop; - this.durationInSeconds = (int) lastState.getElapsedTimeSeconds(); - this.generalizedCost = RaptorCostConverter.toRaptorCost(lastState.getWeight()); - this.lastState = lastState; - this.timePenalty = RaptorConstants.TIME_NOT_SET; - this.penalty = TimeAndCost.ZERO; + this.durationInSeconds = durationInSeconds; + this.generalizedCost = generalizedCost; + this.timePenalty = penalty.isZero() ? RaptorConstants.TIME_NOT_SET : penalty.timeInSeconds(); + this.penalty = penalty; + this.lastState = Objects.requireNonNull(lastState); + } + + public DefaultAccessEgress(int stop, State lastState) { + this( + stop, + (int) lastState.getElapsedTimeSeconds(), + RaptorCostConverter.toRaptorCost(lastState.getWeight()), + TimeAndCost.ZERO, + lastState + ); } protected DefaultAccessEgress(RoutingAccessEgress other, TimeAndCost penalty) { - if (other.hasPenalty()) { - throw new IllegalStateException("Can not add penalty twice..."); - } - this.stop = other.stop(); - this.durationInSeconds = other.durationInSeconds(); // In the API we have a cost associated with the time-penalty. In Raptor, there is no // association between the time-penalty and the cost. So, we add the time-penalty cost to // the generalized cost here. In logic later on, we will remove it. - this.generalizedCost = other.c1() + penalty.cost().toCentiSeconds(); - this.timePenalty = penalty.isZero() ? RaptorConstants.TIME_NOT_SET : penalty.timeInSeconds(); - this.penalty = penalty; - this.lastState = other.getLastState(); + this( + other.stop(), + other.durationInSeconds(), + other.c1() + penalty.cost().toCentiSeconds(), + penalty, + other.getLastState() + ); + if (other.penalty() != TimeAndCost.ZERO) { + throw new IllegalStateException("Can not add penalty twice..."); + } } @Override @@ -83,11 +103,6 @@ public boolean isWalkOnly() { return lastState.containsOnlyWalkMode(); } - @Override - public boolean hasPenalty() { - return !penalty.isZero(); - } - @Override public TimeAndCost penalty() { return penalty; diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/RoutingAccessEgress.java b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/RoutingAccessEgress.java index d22ec0f71f9..dbc260d3d90 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/RoutingAccessEgress.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/RoutingAccessEgress.java @@ -27,7 +27,5 @@ public interface RoutingAccessEgress extends RaptorAccessEgress { */ boolean isWalkOnly(); - boolean hasPenalty(); - TimeAndCost penalty(); } diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/RaptorTestConstants.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/RaptorTestConstants.java index 88a6b97bb75..8a68fcbdcce 100644 --- a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/RaptorTestConstants.java +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/RaptorTestConstants.java @@ -4,7 +4,10 @@ import static org.opentripplanner.utils.time.TimeUtils.hm2time; import org.opentripplanner.raptor.spi.DefaultSlackProvider; +import org.opentripplanner.raptor.spi.RaptorCostCalculator; import org.opentripplanner.raptor.spi.RaptorSlackProvider; +import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; +import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.DefaultCostCalculator; /** * @deprecated This was earlier part of Raptor and should not be used outside the Raptor @@ -16,7 +19,6 @@ public interface RaptorTestConstants { int D0s = 0; int D1s = 1; int D10s = 10; - int D11s = 11; int D20s = 20; int D30s = 30; int D40s = 40; @@ -25,11 +27,6 @@ public interface RaptorTestConstants { int D3m = durationInSeconds("3m"); int D4m = durationInSeconds("4m"); int D5m = durationInSeconds("5m"); - int D7m = durationInSeconds("7m"); - int D8m = durationInSeconds("8m"); - int D10m = durationInSeconds("10m"); - int D11m = durationInSeconds("11m"); - int D20m = durationInSeconds("20m"); int D24h = durationInSeconds("24h"); /** @@ -39,15 +36,6 @@ public interface RaptorTestConstants { // Time constants, all values are in seconds int T00_00 = hm2time(0, 0); - int T00_02 = hm2time(0, 2); - int T00_10 = hm2time(0, 10); - int T00_30 = hm2time(0, 30); - int T00_40 = hm2time(0, 40); - int T01_00 = hm2time(1, 0); - - int TX_0 = 0; - int TX_1 = 1; - int TX_2 = 2; // Stop indexes - Note! There is no stop defined for index 0(zero)! You must // account for that in the test if you use the stop index. @@ -76,15 +64,24 @@ public interface RaptorTestConstants { int ALIGHT_SLACK = 15; int TRANSFER_SLACK = 60; + // COST_CALCULATION + int BOARD_COST = 60; + int TRANSFER_COST = 120; + double WAIT_RELUCTANCE = 0.8; + RaptorSlackProvider SLACK_PROVIDER = new DefaultSlackProvider( TRANSFER_SLACK, BOARD_SLACK, ALIGHT_SLACK ); - // FLEX - int ONE_RIDE = 1; - int TWO_RIDES = 2; + RaptorCostCalculator COST_CALCULATOR = new DefaultCostCalculator<>( + BOARD_COST, + TRANSFER_COST, + WAIT_RELUCTANCE, + null, + null + ); default String stopIndexToName(int index) { return Character.toString('A' + index - 1); diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/api/PathUtils.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/api/PathUtils.java index 15e16217fa2..c602ed95266 100644 --- a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/api/PathUtils.java +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/api/PathUtils.java @@ -3,9 +3,7 @@ import java.util.Collection; import java.util.function.Function; import java.util.stream.Collectors; -import java.util.stream.Stream; import org.opentripplanner.raptor.api.path.RaptorPath; -import org.opentripplanner.raptor.api.response.RaptorResponse; import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; /** @@ -24,34 +22,14 @@ public class PathUtils { /** Util class, private constructor */ private PathUtils() {} - public static String pathsToString(RaptorResponse response) { - return pathsToString(response.paths()); - } - public static String pathsToString(Collection> paths) { return pathsToString(paths, p -> p.toString(TRANSLATOR::stopIndexToName)); } - public static String pathsToStringDetailed(RaptorResponse response) { - return pathsToStringDetailed(response.paths()); - } - public static String pathsToStringDetailed(Collection> paths) { return pathsToString(paths, p -> p.toStringDetailed(TRANSLATOR::stopIndexToName)); } - public static String join(String... paths) { - return String.join("\n", paths); - } - - public static String withoutCost(String path) { - return path.replaceAll(" C₁[\\d_]+", ""); - } - - public static String[] withoutCost(String... paths) { - return Stream.of(paths).map(path -> withoutCost(path)).toList().toArray(new String[0]); - } - public static String pathsToString( Collection> paths, Function, String> mapToStr diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/api/TestPathBuilder.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/api/TestPathBuilder.java index a7fe2f9f3c8..8f0dbc65f42 100644 --- a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/api/TestPathBuilder.java +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/api/TestPathBuilder.java @@ -3,6 +3,7 @@ import static org.opentripplanner.raptor.rangeraptor.transit.TripTimesSearch.findTripTimes; import javax.annotation.Nullable; +import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorConstants; import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.path.RaptorPath; @@ -76,7 +77,7 @@ public TestPathBuilder access(int startTime, int toStop) { * Create access with the given {@code startTime}, but allow the access to be time-shifted * according to the opening hours of the given {@code transfer}. */ - private TestPathBuilder access(int startTime, TestAccessEgress transfer) { + private TestPathBuilder access(int startTime, RaptorAccessEgress transfer) { reset(startTime); builder.access(transfer); return this; @@ -86,10 +87,6 @@ public TestPathBuilder walk(int duration, int toStop) { return walk(TestTransfer.transfer(toStop, duration)); } - public TestPathBuilder walk(int duration, int toStop, int cost) { - return walk(TestTransfer.transfer(toStop, duration, cost)); - } - public TestPathBuilder walk(TestTransfer transfer) { builder.transfer(transfer, transfer.stop()); return this; @@ -126,12 +123,7 @@ public RaptorPath egress(int duration) { ); } - public PathBuilder access(TestAccessEgress access) { - builder.access(access); - return builder; - } - - public RaptorPath egress(TestAccessEgress egress) { + public RaptorPath egress(RaptorAccessEgress egress) { builder.egress(egress); builder.c2(c2); return builder.build(); diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/api/TestPathBuilderTestRaptor.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/api/TestPathBuilderTestRaptor.java deleted file mode 100644 index e68bf7ad7cf..00000000000 --- a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/api/TestPathBuilderTestRaptor.java +++ /dev/null @@ -1,99 +0,0 @@ -package org.opentripplanner.raptorlegacy._data.api; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.opentripplanner.model.transfer.TransferConstraint.REGULAR_TRANSFER; -import static org.opentripplanner.raptorlegacy._data.stoparrival.BasicPathTestCase.C1_CALCULATOR; -import static org.opentripplanner.utils.time.DurationUtils.durationInSeconds; -import static org.opentripplanner.utils.time.TimeUtils.time; - -import org.junit.jupiter.api.Test; -import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; -import org.opentripplanner.raptorlegacy._data.stoparrival.BasicPathTestCase; -import org.opentripplanner.raptorlegacy._data.transit.TestAccessEgress; - -/** - * Test the PathBuilder to be sure that it works properly before using it in other tests. - * - * @deprecated This was earlier part of Raptor and should not be used outside the Raptor - * module. Use the OTP model entities instead. - */ -@Deprecated -public class TestPathBuilderTestRaptor implements RaptorTestConstants { - - private final TestPathBuilder subject = new TestPathBuilder(C1_CALCULATOR); - - @Test - public void testSimplePathWithOneTransit() { - int transitDuration = durationInSeconds("5m"); - - var path = subject - .access(time("10:00:15"), STOP_A, D1m) - .bus("L1", time("10:02"), transitDuration, STOP_B) - .egress(D2m); - - var transitLeg = path.accessLeg().nextLeg().asTransitLeg(); - int boardCost = C1_CALCULATOR.boardingCost( - true, - path.accessLeg().toTime(), - STOP_A, - transitLeg.fromTime(), - transitLeg.trip(), - REGULAR_TRANSFER - ); - - int transitCost = C1_CALCULATOR.transitArrivalCost( - boardCost, - ALIGHT_SLACK, - transitDuration, - BasicPathTestCase.TRIP_1, - STOP_B - ); - - int accessEgressCost = C1_CALCULATOR.costEgress(TestAccessEgress.walk(STOP_B, D2m + D1m)); - - assertEquals(accessEgressCost + transitCost, path.c1()); - assertEquals( - "Walk 1m 10:00:15 10:01:15 C₁120 ~ A 45s " + - "~ BUS L1 10:02 10:07 5m C₁438 ~ B 15s " + - "~ Walk 2m 10:07:15 10:09:15 C₁210 " + - "[10:00:15 10:09:15 9m Tₓ0 C₁768]", - path.toStringDetailed(this::stopIndexToName) - ); - } - - @Test - public void testBasicPath() { - var path = subject - .c2(7) - .access(BasicPathTestCase.ACCESS_START, STOP_A, BasicPathTestCase.ACCESS_DURATION) - .bus( - BasicPathTestCase.LINE_11, - BasicPathTestCase.L11_START, - BasicPathTestCase.L11_DURATION, - STOP_B - ) - .walk(BasicPathTestCase.TX_DURATION, STOP_C, BasicPathTestCase.TX_C1) - .bus( - BasicPathTestCase.LINE_21, - BasicPathTestCase.L21_START, - BasicPathTestCase.L21_DURATION, - STOP_D - ) - .bus( - BasicPathTestCase.LINE_31, - BasicPathTestCase.L31_START, - BasicPathTestCase.L31_DURATION, - STOP_E - ) - .egress(BasicPathTestCase.EGRESS_DURATION); - - assertEquals(BasicPathTestCase.BASIC_PATH_AS_STRING, path.toString(this::stopIndexToName)); - assertEquals( - BasicPathTestCase.BASIC_PATH_AS_DETAILED_STRING, - path.toStringDetailed(this::stopIndexToName) - ); - assertEquals(BasicPathTestCase.TOTAL_C1, path.c1()); - assertTrue(path.isC2Set()); - } -} diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/AbstractStopArrival.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/AbstractStopArrival.java deleted file mode 100644 index bb4edf3a6a7..00000000000 --- a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/AbstractStopArrival.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.opentripplanner.raptorlegacy._data.stoparrival; - -import org.opentripplanner.raptor.api.view.ArrivalView; -import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; - -/** - * @deprecated This was earlier part of Raptor and should not be used outside the Raptor - * module. Use the OTP model entities instead. - */ -@Deprecated -abstract class AbstractStopArrival implements ArrivalView { - - private final int round; - private final int stop; - private final int arrivalTime; - private final int c1; - private final int c2; - private final ArrivalView previous; - - AbstractStopArrival( - int round, - int stop, - int arrivalTime, - int extraCost, - int c2, - ArrivalView previous - ) { - this.round = round; - this.stop = stop; - this.arrivalTime = arrivalTime; - this.previous = previous; - this.c2 = c2; - - if (previous == null) { - this.c1 = extraCost; - } else { - this.c1 = previous.c1() + extraCost; - } - } - - AbstractStopArrival( - int round, - int stop, - int arrivalTime, - int extraCost, - ArrivalView previous - ) { - this(round, stop, arrivalTime, extraCost, previous.c2(), previous); - } - - @Override - public int stop() { - return stop; - } - - @Override - public int round() { - return round; - } - - @Override - public int arrivalTime() { - return arrivalTime; - } - - @Override - public int c1() { - return c1; - } - - @Override - public int c2() { - return c2; - } - - @Override - public ArrivalView previous() { - return previous; - } - - @Override - public String toString() { - return asString(); - } -} diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Access.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Access.java deleted file mode 100644 index bb2fa1f481b..00000000000 --- a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Access.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.opentripplanner.raptorlegacy._data.stoparrival; - -import static org.opentripplanner.raptor.api.model.PathLegType.ACCESS; - -import org.opentripplanner.raptor.api.model.PathLegType; -import org.opentripplanner.raptor.api.model.RaptorAccessEgress; -import org.opentripplanner.raptor.api.view.AccessPathView; - -/** - * @deprecated This was earlier part of Raptor and should not be used outside the Raptor - * module. Use the OTP model entities instead. - */ -@Deprecated -class Access extends AbstractStopArrival { - - private final RaptorAccessEgress access; - - Access(int stop, int arrivalTime, RaptorAccessEgress path, int c2) { - super(0, stop, arrivalTime, path.c1(), c2, null); - this.access = path; - } - - @Override - public PathLegType arrivedBy() { - return ACCESS; - } - - @Override - public AccessPathView accessPath() { - return () -> access; - } - - @Override - public boolean arrivedOnBoard() { - return access.stopReachedOnBoard(); - } -} diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Egress.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Egress.java deleted file mode 100644 index 9b781b0beb0..00000000000 --- a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Egress.java +++ /dev/null @@ -1,54 +0,0 @@ -package org.opentripplanner.raptorlegacy._data.stoparrival; - -import org.opentripplanner.raptor.api.model.PathLegType; -import org.opentripplanner.raptor.api.model.RaptorAccessEgress; -import org.opentripplanner.raptor.api.view.ArrivalView; -import org.opentripplanner.raptor.api.view.EgressPathView; -import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; -import org.opentripplanner.utils.time.TimeUtils; - -/** - * @deprecated This was earlier part of Raptor and should not be used outside the Raptor - * module. Use the OTP model entities instead. - */ -@Deprecated -public class Egress extends AbstractStopArrival { - - private final RaptorAccessEgress egressPath; - - public Egress( - int arrivalTime, - RaptorAccessEgress egressPath, - int c2, - ArrivalView previous - ) { - super(previous.round(), previous.stop(), arrivalTime, egressPath.c1(), c2, previous); - this.egressPath = egressPath; - } - - @Override - public EgressPathView egressPath() { - return () -> egressPath; - } - - @Override - public String toString() { - return String.format( - "Egress { round: %d, stop: %d, arrival-time: %s $%d }", - round(), - stop(), - TimeUtils.timeToStrCompact(arrivalTime()), - c1() - ); - } - - @Override - public PathLegType arrivedBy() { - return PathLegType.EGRESS; - } - - @Override - public boolean arrivedOnBoard() { - return egressPath.stopReachedOnBoard(); - } -} diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/FlexAccessAndEgressPathTestCase.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/FlexAccessAndEgressPathTestCase.java deleted file mode 100644 index 99dd81ebbb7..00000000000 --- a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/FlexAccessAndEgressPathTestCase.java +++ /dev/null @@ -1,386 +0,0 @@ -package org.opentripplanner.raptorlegacy._data.stoparrival; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.raptor.api.model.RaptorCostConverter.toRaptorCost; -import static org.opentripplanner.raptor.api.model.RaptorValueFormatter.formatC1; -import static org.opentripplanner.utils.time.DurationUtils.durationInSeconds; -import static org.opentripplanner.utils.time.TimeUtils.time; - -import org.junit.jupiter.api.Test; -import org.opentripplanner.raptor.api.model.RaptorAccessEgress; -import org.opentripplanner.raptor.api.model.RaptorConstants; -import org.opentripplanner.raptor.api.model.RaptorCostConverter; -import org.opentripplanner.raptor.api.model.RaptorTransfer; -import org.opentripplanner.raptor.api.view.ArrivalView; -import org.opentripplanner.raptor.rangeraptor.path.DestinationArrival; -import org.opentripplanner.raptor.spi.DefaultSlackProvider; -import org.opentripplanner.raptor.spi.RaptorSlackProvider; -import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; -import org.opentripplanner.raptorlegacy._data.transit.TestAccessEgress; -import org.opentripplanner.raptorlegacy._data.transit.TestTransfer; -import org.opentripplanner.raptorlegacy._data.transit.TestTripPattern; -import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; -import org.opentripplanner.routing.algorithm.raptoradapter.transit.cost.DefaultCostCalculator; -import org.opentripplanner.utils.time.TimeUtils; - -/** - * This test case construct two Raptor paths for forward and reverse search, with and without - * opening hours for the flex access and egress. - *

- * Case A with flex access and egress and one transit: - *

    - *
  1. Flex access
  2. - *
  3. Transit, BUS A
  4. - *
  5. Flex
  6. - *
- *

- * Case B with walking between transit and flex: - *

    - *
  1. Flex access
  2. - *
  3. Walk transfer
  4. - *
  5. Transit. BUS B
  6. - *
  7. Walk transfer
  8. - *
  9. Flex
  10. - *
- * - * @deprecated This was earlier part of Raptor and should not be used outside the Raptor - * module. Use the OTP model entities instead. - */ -@Deprecated -public class FlexAccessAndEgressPathTestCase implements RaptorTestConstants { - - private static final int ZERO = 0; - // The transit reluctance is ignored, any value should work - private static final int TRANSIT_RELUCTANCE_INDEX = -1; - public static final double WAIT_RELUCTANCE = 0.8; - public static final int BOARD_C1_SEC = 60; - public static final int TRANSFER_C1_SEC = 120; - // The C1_CALCULATOR is not under test, so we use it to calculate correct cost values. - public static final DefaultCostCalculator C1_CALCULATOR = new DefaultCostCalculator<>( - BOARD_C1_SEC, - TRANSFER_C1_SEC, - WAIT_RELUCTANCE, - null, - null - ); - - public static final RaptorSlackProvider SLACK_PROVIDER = new DefaultSlackProvider( - TRANSFER_SLACK, - BOARD_SLACK, - ALIGHT_SLACK - ); - - // FLEX Access 5m tx 1 ~ A. Note! The actual times might get time-shifted. - public static final int ACCESS_DURATION = durationInSeconds("5m15s"); - public static final int ACCESS_C1 = toRaptorCost(600); - // Using transfer reluctance is incorrect, we should use the cost from the access path - public static final TestAccessEgress ACCESS = TestAccessEgress.flex( - STOP_A, - ACCESS_DURATION, - ONE_RIDE, - ACCESS_C1 - ); - // Alternative Flex access with restricted opening hours: 09:00 - 09:50 - public static final int ACCESS_OPEN = time("09:00"); - public static final int ACCESS_CLOSE = time("09:50"); - public static final TestAccessEgress ACCESS_W_OPENING_HOURS = ACCESS.openingHours( - ACCESS_OPEN, - ACCESS_CLOSE - ); - - // Transfers (A ~ Walk 1m ~ B) (Used in Case B only) - public static final int TX1_START = time("10:05:15"); - public static final int TX1_END = time("10:06:15"); - public static final int TX1_DURATION = TX1_END - TX1_START; - public static final RaptorTransfer TX1_TRANSFER = TestTransfer.transfer(STOP_B, TX1_DURATION); - public static final RaptorTransfer TX1_TRANSFER_REV = TestTransfer.transfer(STOP_A, TX1_DURATION); - public static final int TX1_C1 = TX1_TRANSFER.c1(); - - // Trip A (B ~ BUS L11 10:08 10:20 ~ C) - public static final int L1_START = time("10:08"); - public static final int L1_END = time("10:20"); - // The departure time with transfer_slack excluded - public static final int L1_STOP_ARR_TIME = L1_END + ALIGHT_SLACK; - public static final int L1_STOP_ARR_TIME_REV = L1_START - BOARD_SLACK; - - // Wait at least 1m45s (45s BOARD_SLACK and 60s TRANSFER_SLACK) - public static final int L1_TRANSIT_DURATION = L1_END - L1_START; - - // Transfers (C ~ Walk 2m ~ D) (Used in Case B only) - public static final int TX2_START = time("10:20:15"); - public static final int TX2_END = time("10:22:15"); - public static final int TX2_DURATION = TX2_END - TX2_START; - public static final RaptorTransfer TX2_TRANSFER = TestTransfer.transfer(STOP_D, TX2_DURATION); - public static final RaptorTransfer TX2_TRANSFER_REV = TestTransfer.transfer(STOP_C, TX2_DURATION); - public static final int TX2_C1 = TX2_TRANSFER.c1(); - - // Wait 15s (ALIGHT_SLACK) - // D ~ FLEX Egress 6m tx 1 . Note! The actual times might get time-shifted. - public static final int EGRESS_DURATION = durationInSeconds("6m"); - public static final int EGRESS_C1 = toRaptorCost(800); - // Using transfer reluctance is incorrect, we should use the cost from the egress path - public static final TestAccessEgress EGRESS = TestAccessEgress.flex( - STOP_D, - EGRESS_DURATION, - ONE_RIDE, - EGRESS_C1 - ); - public static final int EGRESS_OPENING = TimeUtils.time("10:30"); - public static final int EGRESS_CLOSING = TimeUtils.time("11:00"); - public static final TestAccessEgress EGRESS_W_OPENING_HOURS = EGRESS.openingHours( - EGRESS_OPENING, - EGRESS_CLOSING - ); - - public static final int EGRESS_C1_W_1M_SLACK = - EGRESS_C1 + toRaptorCost(TRANSFER_C1_SEC) + C1_CALCULATOR.waitCost(TRANSFER_SLACK); - public static final int EGRESS_C1_W_7M45S_SLACK = - EGRESS_C1_W_1M_SLACK + C1_CALCULATOR.waitCost(durationInSeconds("6m45s")); - public static final int EGRESS_C1_W_9M45S_SLACK = - EGRESS_C1_W_1M_SLACK + C1_CALCULATOR.waitCost(durationInSeconds("8m45s")); - - public static final String LINE_A = "A"; - public static final String LINE_B = "B"; - - public static final TestTripSchedule TRIP_A = TestTripSchedule - .schedule(TestTripPattern.pattern(LINE_A, STOP_A, STOP_D)) - .times(L1_START, L1_END) - .transitReluctanceIndex(TRANSIT_RELUCTANCE_INDEX) - .build(); - - public static final TestTripSchedule TRIP_B = TestTripSchedule - .schedule(TestTripPattern.pattern(LINE_B, STOP_B, STOP_C)) - .times(L1_START, L1_END) - .transitReluctanceIndex(TRANSIT_RELUCTANCE_INDEX) - .build(); - - public static final int L1_C1_EX_WAIT = C1_CALCULATOR.transitArrivalCost( - C1_CALCULATOR.boardingCostRegularTransfer(false, L1_START, STOP_B, L1_START), - ZERO, - L1_TRANSIT_DURATION, - TRIP_A, - STOP_C - ); - - private static final int TOT_C1_A = toRaptorCost(2564); - private static final int TOT_C1_W_OPENING_HOURS_A = toRaptorCost(3512); - private static final int TOT_C1_B = toRaptorCost(2924); - private static final int TOT_C1_W_OPENING_HOURS_B = toRaptorCost(3728); - // Wait before 12m45s + ALIGHT SLACK 15s - private static final int L1_C1_INC_WAIT_W_OPENING_HOURS_A = - L1_C1_EX_WAIT + C1_CALCULATOR.waitCost(durationInSeconds("13m")); - private static final int L1_C1_INC_WAIT_W_OPENING_HOURS_B = - L1_C1_EX_WAIT + C1_CALCULATOR.waitCost(durationInSeconds("12m")); - - /* TEST CASES WITH EXPECTED TO-STRING TEXTS */ - - public static DestinationArrival flexCaseAForwardSearch() { - return flexForwardSearch(ACCESS, EGRESS, LINE_A); - } - - public static String flexCaseAText() { - return String.format( - "Flex 5m15s 1x 10:01 10:06:15 %s ~ A 1m45s ~ " + - "BUS A 10:08 10:20 12m C₁996 ~ D 1m15s ~ " + - "Flex 6m 1x 10:21:15 10:27:15 %s " + - "[10:01 10:27:15 26m15s Tₓ2 %s]", - RaptorCostConverter.toString(ACCESS_C1), - RaptorCostConverter.toString(EGRESS_C1_W_1M_SLACK), - RaptorCostConverter.toString(TOT_C1_A) - ); - } - - public static DestinationArrival flexCaseBForwardSearch() { - return flexForwardSearch(ACCESS, EGRESS, LINE_B); - } - - public static String flexCaseBText() { - return String.format( - "Flex 5m15s 1x 10:00 10:05:15 %s ~ A 0s ~ " + - "Walk 1m 10:05:15 10:06:15 C₁120 ~ B 1m45s ~ " + - "BUS B 10:08 10:20 12m C₁996 ~ C 15s ~ " + - "Walk 2m 10:20:15 10:22:15 C₁240 ~ D 1m ~ " + - "Flex 6m 1x 10:23:15 10:29:15 %s" + - " [10:00 10:29:15 29m15s Tₓ2 %s]", - RaptorCostConverter.toString(ACCESS_C1), - RaptorCostConverter.toString(EGRESS_C1_W_1M_SLACK), - RaptorCostConverter.toString(TOT_C1_B) - ); - } - - public static DestinationArrival flexCaseAWithOpeningHoursForwardSearch() { - return flexForwardSearch(ACCESS_W_OPENING_HOURS, EGRESS_W_OPENING_HOURS, LINE_A); - } - - public static String flexCaseAWithOpeningHoursText() { - return String.format( - "Flex 5m15s 1x Open(9:00 9:50) 9:50 9:55:15 %s ~ A 12m45s ~ " + - "BUS A 10:08 10:20 12m %s ~ D 10m ~ " + - "Flex 6m 1x Open(10:30 11:00) 10:30 10:36 %s " + - "[9:50 10:36 46m Tₓ2 %s]", - formatC1(ACCESS_C1), - formatC1(L1_C1_INC_WAIT_W_OPENING_HOURS_A), - formatC1(EGRESS_C1_W_9M45S_SLACK), - formatC1(TOT_C1_W_OPENING_HOURS_A) - ); - } - - public static DestinationArrival flexCaseBWithOpeningHoursForwardSearch() { - return flexForwardSearch(ACCESS_W_OPENING_HOURS, EGRESS_W_OPENING_HOURS, LINE_B); - } - - public static String flexCaseBWithOpeningHoursText() { - return String.format( - "Flex 5m15s 1x Open(9:00 9:50) 9:50 9:55:15 %s ~ A 0s ~ " + - "Walk 1m 9:55:15 9:56:15 C₁120 ~ B 11m45s ~ " + - "BUS B 10:08 10:20 12m %s ~ C 15s ~ " + - "Walk 2m 10:20:15 10:22:15 C₁240 ~ D 7m45s ~ " + - "Flex 6m 1x Open(10:30 11:00) 10:30 10:36 %s" + - " [9:50 10:36 46m Tₓ2 %s]", - formatC1(ACCESS_C1), - formatC1(L1_C1_INC_WAIT_W_OPENING_HOURS_B), - formatC1(EGRESS_C1_W_7M45S_SLACK), - formatC1(TOT_C1_W_OPENING_HOURS_B) - ); - } - - public static DestinationArrival flexCaseAReverseSearch() { - return flexReverseSearch(ACCESS, EGRESS, LINE_A); - } - - public static DestinationArrival flexCaseBReverseSearch() { - return flexReverseSearch(ACCESS, EGRESS, LINE_B); - } - - public static DestinationArrival flexCaseAWithOpeningHoursReverseSearch() { - return flexReverseSearch(ACCESS_W_OPENING_HOURS, EGRESS_W_OPENING_HOURS, LINE_A); - } - - public static DestinationArrival flexCaseBWithOpeningHoursReverseSearch() { - return flexReverseSearch(ACCESS_W_OPENING_HOURS, EGRESS_W_OPENING_HOURS, LINE_B); - } - - @Test - public void testSetup() { - // Assert test data is configured correct - - // Assert all durations - assertEquals(TX1_END - TX1_START, TX1_DURATION); - assertEquals(L1_END - L1_START, L1_TRANSIT_DURATION); - assertEquals(TX2_END - TX2_START, TX2_DURATION); - - // Asset proper wait times - int txBoardSlack = TRANSFER_SLACK + BOARD_SLACK; - assertEquals(TX1_END + txBoardSlack, L1_START); - assertEquals(L1_END + ALIGHT_SLACK, TX2_START); - - // Assert cost - // The calculator is not under test here, so we assert everything is as expected - assertEquals(12000, TX1_C1); - assertEquals(90000, L1_C1_EX_WAIT); - assertEquals(24000, TX2_C1); - } - - /* PRIVATE METHODS */ - - private static DestinationArrival flexForwardSearch( - RaptorAccessEgress accessPath, - RaptorAccessEgress egressPath, - String line - ) { - int departureTime, arrivalTime, waitTime; - ArrivalView prevArrival; - - if (LINE_A.equals(line)) { - // The latest time the access can arrive is the same as the TX1 arrival time in case B - arrivalTime = accessPath.latestArrivalTime(TX1_END); - prevArrival = TestArrivals.access(accessPath.stop(), arrivalTime, accessPath); - - int waitCost = costL1ForwardIncWait(prevArrival.arrivalTime()); - prevArrival = TestArrivals.bus(2, STOP_D, L1_STOP_ARR_TIME, waitCost, 0, TRIP_A, prevArrival); - } else { - arrivalTime = accessPath.latestArrivalTime(TX1_START); - prevArrival = TestArrivals.access(accessPath.stop(), arrivalTime, accessPath); - int timeShift = TX1_START - prevArrival.arrivalTime(); - - prevArrival = new Transfer(1, TX1_END - timeShift, TX1_TRANSFER, prevArrival); - - int waitCost = costL1ForwardIncWait(prevArrival.arrivalTime()); - prevArrival = TestArrivals.bus(2, STOP_C, L1_STOP_ARR_TIME, waitCost, 0, TRIP_B, prevArrival); - - prevArrival = new Transfer(2, TX2_END, TX2_TRANSFER, prevArrival); - } - - // Egress - departureTime = prevArrival.arrivalTime() + TRANSFER_SLACK; - // Time-shift departure time - departureTime = egressPath.earliestDepartureTime(departureTime); - arrivalTime = departureTime + egressPath.durationInSeconds(); - waitTime = departureTime - prevArrival.arrivalTime(); - int additionalCost = - egressPath.c1() + toRaptorCost(waitTime * WAIT_RELUCTANCE + TRANSFER_C1_SEC); - - return new DestinationArrival<>( - egressPath, - prevArrival, - arrivalTime, - additionalCost, - RaptorConstants.NOT_SET - ); - } - - private static DestinationArrival flexReverseSearch( - RaptorAccessEgress accessPath, - RaptorAccessEgress egressPath, - String line - ) { - int departureTime, arrivalTime, cost; - ArrivalView prevArrival; - - if (LINE_A.equals(line)) { - arrivalTime = L1_END + ALIGHT_SLACK + TRANSFER_SLACK; - arrivalTime = egressPath.earliestDepartureTime(arrivalTime); - prevArrival = TestArrivals.access(egressPath.stop(), arrivalTime, egressPath); - - cost = costL1ReverseIncWait(prevArrival.arrivalTime()); - prevArrival = TestArrivals.bus(2, STOP_A, L1_STOP_ARR_TIME_REV, cost, 0, TRIP_A, prevArrival); - } else { - arrivalTime = L1_END + ALIGHT_SLACK + TX2_DURATION + TRANSFER_SLACK; - arrivalTime = egressPath.earliestDepartureTime(arrivalTime); - prevArrival = TestArrivals.access(egressPath.stop(), arrivalTime, egressPath); - arrivalTime = prevArrival.arrivalTime() - TX2_DURATION; - prevArrival = new Transfer(1, arrivalTime, TX2_TRANSFER_REV, prevArrival); - cost = costL1ReverseIncWait(prevArrival.arrivalTime()); - prevArrival = TestArrivals.bus(2, STOP_B, L1_STOP_ARR_TIME_REV, cost, 0, TRIP_B, prevArrival); - arrivalTime = prevArrival.arrivalTime() - TX1_DURATION; - prevArrival = new Transfer(2, arrivalTime, TX1_TRANSFER_REV, prevArrival); - } - - // Access - departureTime = prevArrival.arrivalTime() - TRANSFER_SLACK; - // Time-shift departure time - departureTime = accessPath.latestArrivalTime(departureTime); - arrivalTime = departureTime - accessPath.durationInSeconds(); - int waitTime = prevArrival.arrivalTime() - departureTime; - int additionalCost = - accessPath.c1() + toRaptorCost(waitTime * WAIT_RELUCTANCE + TRANSFER_C1_SEC); - - return new DestinationArrival<>( - accessPath, - prevArrival, - arrivalTime, - additionalCost, - RaptorConstants.NOT_SET - ); - } - - private static int costL1ForwardIncWait(int prevArrivalTime) { - int waitTime = L1_START - prevArrivalTime + ALIGHT_SLACK; - return toRaptorCost(waitTime * WAIT_RELUCTANCE) + L1_C1_EX_WAIT; - } - - private static int costL1ReverseIncWait(int prevArrivalTime) { - int waitTime = (prevArrivalTime - L1_END) + BOARD_SLACK; - return toRaptorCost(waitTime * WAIT_RELUCTANCE) + L1_C1_EX_WAIT; - } -} diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/TestArrivals.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/TestArrivals.java deleted file mode 100644 index 4ea0398efa4..00000000000 --- a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/TestArrivals.java +++ /dev/null @@ -1,110 +0,0 @@ -package org.opentripplanner.raptorlegacy._data.stoparrival; - -import org.opentripplanner.raptor.api.model.RaptorAccessEgress; -import org.opentripplanner.raptor.api.model.RaptorConstants; -import org.opentripplanner.raptor.api.model.RaptorTransfer; -import org.opentripplanner.raptor.api.view.ArrivalView; -import org.opentripplanner.raptorlegacy._data.transit.TestAccessEgress; -import org.opentripplanner.raptorlegacy._data.transit.TestTransfer; -import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; - -/** - * @deprecated This was earlier part of Raptor and should not be used outside the Raptor - * module. Use the OTP model entities instead. - */ -@Deprecated -public class TestArrivals { - - public static ArrivalView access( - int stop, - int arrivalTime, - RaptorAccessEgress path, - int c2 - ) { - return new Access(stop, arrivalTime, path, c2); - } - - public static ArrivalView access( - int stop, - int arrivalTime, - RaptorAccessEgress path - ) { - return access(stop, arrivalTime, path, RaptorConstants.NOT_SET); - } - - public static ArrivalView access( - int stop, - int departureTime, - int arrivalTime, - int c1, - int c2 - ) { - return access( - stop, - arrivalTime, - TestAccessEgress.walk(stop, Math.abs(arrivalTime - departureTime), c1), - c2 - ); - } - - public static ArrivalView access( - int stop, - int departureTime, - int arrivalTime, - int c1 - ) { - return access(stop, departureTime, arrivalTime, c1, RaptorConstants.NOT_SET); - } - - public static ArrivalView transfer( - int round, - int arrivalTime, - RaptorTransfer transfer, - ArrivalView previous - ) { - return new Transfer(round, arrivalTime, transfer, previous); - } - - public static ArrivalView transfer( - int round, - int stop, - int departureTime, - int arrivalTime, - int extraCost, - ArrivalView previous - ) { - return transfer( - round, - arrivalTime, - TestTransfer.transfer(stop, Math.abs(arrivalTime - departureTime), extraCost), - previous - ); - } - - public static ArrivalView bus( - int round, - int stop, - int arrivalTime, - int c1, - int c2, - TestTripSchedule trip, - ArrivalView previous - ) { - return new Transit(round, stop, arrivalTime, c1, c2, trip, previous); - } - - public static ArrivalView egress( - int departureTime, - int arrivalTime, - int c1, - int c2, - ArrivalView previous - ) { - return new Egress( - departureTime, - TestAccessEgress.walk(previous.stop(), Math.abs(arrivalTime - departureTime), c1), - c2, - previous - ); - } -} diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Transfer.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Transfer.java deleted file mode 100644 index 56363c4fdde..00000000000 --- a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Transfer.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.opentripplanner.raptorlegacy._data.stoparrival; - -import static org.opentripplanner.raptor.api.model.PathLegType.TRANSFER; - -import org.opentripplanner.raptor.api.model.PathLegType; -import org.opentripplanner.raptor.api.model.RaptorTransfer; -import org.opentripplanner.raptor.api.view.ArrivalView; -import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; - -/* - * @deprecated This was earlier part of Raptor and should not be used outside the Raptor - * module. Use the OTP model entities instead. - */ -@Deprecated -class Transfer extends AbstractStopArrival { - - private final RaptorTransfer transfer; - - Transfer( - int round, - int arrivalTime, - RaptorTransfer transfer, - ArrivalView previous - ) { - super(round, transfer.stop(), arrivalTime, transfer.c1(), previous.c2(), previous); - this.transfer = transfer; - } - - @Override - public PathLegType arrivedBy() { - return TRANSFER; - } - - @Override - public RaptorTransfer transfer() { - return transfer; - } - - @Override - public boolean arrivedOnBoard() { - return false; - } -} diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Transit.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Transit.java deleted file mode 100644 index 5de1cdbd4dc..00000000000 --- a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/Transit.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.opentripplanner.raptorlegacy._data.stoparrival; - -import static org.opentripplanner.raptor.api.model.PathLegType.TRANSIT; - -import org.opentripplanner.raptor.api.model.PathLegType; -import org.opentripplanner.raptor.api.view.ArrivalView; -import org.opentripplanner.raptor.api.view.TransitPathView; -import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; - -/** - * - * @deprecated This was earlier part of Raptor and should not be used outside the Raptor - * module. Use the OTP model entities instead. - */ -@Deprecated -class Transit extends AbstractStopArrival implements TransitPathView { - - private final TestTripSchedule trip; - - Transit( - int round, - int stop, - int arrivalTime, - int c1, - int c2, - TestTripSchedule trip, - ArrivalView previous - ) { - super(round, stop, arrivalTime, c1, c2, previous); - this.trip = trip; - } - - @Override - public PathLegType arrivedBy() { - return TRANSIT; - } - - @Override - public TransitPathView transitPath() { - return this; - } - - @Override - public int boardStop() { - return previous().stop(); - } - - @Override - public TestTripSchedule trip() { - return trip; - } - - @Override - public boolean arrivedOnBoard() { - return true; - } -} diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestAccessEgress.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestAccessEgress.java index 6fb26c22dfb..37149c1baf2 100644 --- a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestAccessEgress.java +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestAccessEgress.java @@ -1,68 +1,28 @@ package org.opentripplanner.raptorlegacy._data.transit; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.raptor.api.model.RaptorCostConverter.toRaptorCost; -import static org.opentripplanner.raptorlegacy._data.RaptorTestConstants.SECONDS_IN_A_DAY; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import org.opentripplanner.raptor.api.model.RaptorAccessEgress; -import org.opentripplanner.raptor.api.model.RaptorConstants; -import org.opentripplanner.utils.time.TimeUtils; +import org.opentripplanner._support.geometry.Coordinates; +import org.opentripplanner.framework.i18n.I18NString; +import org.opentripplanner.framework.model.TimeAndCost; +import org.opentripplanner.routing.algorithm.raptoradapter.transit.DefaultAccessEgress; +import org.opentripplanner.routing.algorithm.raptoradapter.transit.RoutingAccessEgress; +import org.opentripplanner.street.model.vertex.StreetLocation; +import org.opentripplanner.street.search.request.StreetSearchRequest; +import org.opentripplanner.street.search.state.State; +import org.opentripplanner.utils.lang.IntUtils; /** - * Simple implementation for {@link RaptorAccessEgress} for use in unit-tests. - * - * @deprecated This was earlier part of Raptor and should not be used outside the Raptor - * module. Use the OTP model entities instead. + * Utility class for creating access/egress for unit-tests. */ -@Deprecated -public class TestAccessEgress implements RaptorAccessEgress { +public class TestAccessEgress { - public static final int DEFAULT_NUMBER_OF_RIDES = 0; + public static final int ZERO = 0; public static final boolean STOP_REACHED_ON_BOARD = true; public static final boolean STOP_REACHED_ON_FOOT = false; public static final double DEFAULT_WALK_RELUCTANCE = 2.0; - private final int stop; - private final int durationInSeconds; - private final int c1; - private final int numberOfRides; - private final boolean stopReachedOnBoard; - private final boolean free; - private final Integer opening; - private final Integer closing; - private final boolean closed; - private final int timePenalty; - - private TestAccessEgress(Builder builder) { - this.stop = builder.stop; - this.durationInSeconds = builder.durationInSeconds; - this.numberOfRides = builder.numberOfRides; - this.stopReachedOnBoard = builder.stopReachedOnBoard; - this.free = builder.free; - this.opening = builder.opening; - this.closing = builder.closing; - this.closed = builder.closed; - this.timePenalty = builder.timePenalty; - this.c1 = builder.c1; - - if (free) { - assertEquals(0, durationInSeconds); - } else { - assertTrue(durationInSeconds > 0); - } - if (closed) { - assertNull(opening); - assertNull(closing); - } - assertTrue(numberOfRides >= 0); - } - - public static TestAccessEgress free(int stop) { + public static RoutingAccessEgress free(int stop) { return new Builder(stop, 0).withFree().build(); } @@ -71,23 +31,19 @@ public static TestAccessEgress free(int stop) { * access/egress. */ @Deprecated - public static TestAccessEgress free(int stop, int cost) { + public static RoutingAccessEgress free(int stop, int cost) { return new Builder(stop, 0).withFree().withCost(cost).build(); } - public static TestAccessEgress walk(int stop, int durationInSeconds) { + public static RoutingAccessEgress walk(int stop, int durationInSeconds) { return new Builder(stop, durationInSeconds).build(); } - public static TestAccessEgress walk(int stop, int durationInSeconds, double walkReluctance) { - return walk(stop, durationInSeconds, walkCost(durationInSeconds, walkReluctance)); - } - - public static TestAccessEgress walk(int stop, int durationInSeconds, int cost) { + public static RoutingAccessEgress walk(int stop, int durationInSeconds, int cost) { return new Builder(stop, durationInSeconds).withCost(cost).build(); } - public static TestAccessEgress flexWithOnBoard(int stop, int durationInSeconds, int cost) { + public static RoutingAccessEgress flexWithOnBoard(int stop, int durationInSeconds, int cost) { return new Builder(stop, durationInSeconds) .withCost(cost) .withNRides(1) @@ -95,19 +51,9 @@ public static TestAccessEgress flexWithOnBoard(int stop, int durationInSeconds, .build(); } - /** Create a new flex access and arrive stop onBoard with 1 ride/extra transfer. */ - public static TestAccessEgress flex(int stop, int durationInSeconds) { - return flex(stop, durationInSeconds, 1, walkCost(durationInSeconds)); - } - - /** Create a new flex access and arrive stop onBoard with 1 ride/extra transfer. */ - public static TestAccessEgress flex(int stop, int durationInSeconds, int nRides) { - return flex(stop, durationInSeconds, nRides, walkCost(durationInSeconds)); - } - /** Create a new flex access and arrive stop onBoard. */ - public static TestAccessEgress flex(int stop, int durationInSeconds, int nRides, int cost) { - assert nRides > DEFAULT_NUMBER_OF_RIDES; + public static RoutingAccessEgress flex(int stop, int durationInSeconds, int nRides, int cost) { + IntUtils.requireInRange(nRides, 1, 100); return new Builder(stop, durationInSeconds) .stopReachedOnBoard() .withNRides(nRides) @@ -115,35 +61,6 @@ public static TestAccessEgress flex(int stop, int durationInSeconds, int nRides, .build(); } - /** Create a flex access arriving at given stop by walking with 1 ride/extra transfer. */ - public static TestAccessEgress flexAndWalk(int stop, int durationInSeconds) { - return flexAndWalk(stop, durationInSeconds, 1, walkCost(durationInSeconds)); - } - - /** Create a flex access arriving at given stop by walking with 1 ride/extra transfer. */ - public static TestAccessEgress flexAndWalk(int stop, int durationInSeconds, int nRides) { - return flexAndWalk(stop, durationInSeconds, nRides, walkCost(durationInSeconds)); - } - - /** Create a flex access arriving at given stop by walking. */ - public static TestAccessEgress flexAndWalk( - int stop, - int durationInSeconds, - int nRides, - int cost - ) { - assert nRides > DEFAULT_NUMBER_OF_RIDES; - return new Builder(stop, durationInSeconds).withNRides(nRides).withCost(cost).build(); - } - - public static Collection transfers(int... stopTimes) { - List legs = new ArrayList<>(); - for (int i = 0; i < stopTimes.length; i += 2) { - legs.add(walk(stopTimes[i], stopTimes[i + 1])); - } - return legs; - } - public static int walkCost(int durationInSeconds) { return walkCost(durationInSeconds, DEFAULT_WALK_RELUCTANCE); } @@ -152,126 +69,6 @@ public static int walkCost(int durationInSeconds, double reluctance) { return toRaptorCost(durationInSeconds * reluctance); } - /** - * Add opening and closing hours and return a new object. - *

- * Opening and closing is specified as seconds since the start of "RAPTOR time" to limit the - * time periods that the access is traversable, which is repeatead every 24 hours. This allows - * access to only be traversable between given times like 08:00 and 16:00 every day. - */ - public TestAccessEgress openingHours(int opening, int closing) { - return copyOf().withOpeningHours(opening, closing).build(); - } - - /** Alias for {@code openingHours(TimeUtils.time(opening), TimeUtils.time(closing))} */ - public TestAccessEgress openingHours(String opening, String closing) { - return openingHours(TimeUtils.time(opening), TimeUtils.time(closing)); - } - - public TestAccessEgress openingHoursClosed() { - return copyOf().withClosed().build(); - } - - public TestAccessEgress withTimePenalty(int timePenalty) { - return this.copyOf().withTimePenalty(timePenalty).build(); - } - - public Builder copyOf() { - return new Builder(this); - } - - @Override - public int stop() { - return stop; - } - - @Override - public int c1() { - return c1; - } - - @Override - public int durationInSeconds() { - return durationInSeconds; - } - - @Override - public int timePenalty() { - return timePenalty; - } - - @Override - public int earliestDepartureTime(int requestedDepartureTime) { - if (!hasOpeningHours()) { - return requestedDepartureTime; - } - if (closed) { - return RaptorConstants.TIME_NOT_SET; - } - - int days = Math.floorDiv(requestedDepartureTime, SECONDS_IN_A_DAY); - int specificOpening = days * SECONDS_IN_A_DAY + opening; - int specificClosing = days * SECONDS_IN_A_DAY + closing; - - if (requestedDepartureTime < specificOpening) { - return specificOpening; - } else if (requestedDepartureTime > specificClosing) { - // return the opening time for the next day - return specificOpening + SECONDS_IN_A_DAY; - } - return requestedDepartureTime; - } - - @Override - public int latestArrivalTime(int requestedArrivalTime) { - if (!hasOpeningHours()) { - return requestedArrivalTime; - } - if (closed) { - return RaptorConstants.TIME_NOT_SET; - } - - // opening & closing is relative to the departure - int requestedDepartureTime = requestedArrivalTime - durationInSeconds(); - int days = Math.floorDiv(requestedDepartureTime, SECONDS_IN_A_DAY); - int specificOpening = days * SECONDS_IN_A_DAY + opening; - int specificClosing = days * SECONDS_IN_A_DAY + closing; - int closeAtArrival = specificClosing + durationInSeconds(); - - if (requestedDepartureTime < specificOpening) { - // return the closing for the previous day, offset with durationInSeconds() - return closeAtArrival - SECONDS_IN_A_DAY; - } else if (requestedArrivalTime > closeAtArrival) { - return closeAtArrival; - } - return requestedArrivalTime; - } - - @Override - public boolean hasOpeningHours() { - return closed || opening != null || closing != null; - } - - @Override - public int numberOfRides() { - return numberOfRides; - } - - @Override - public boolean stopReachedOnBoard() { - return stopReachedOnBoard; - } - - @Override - public boolean isFree() { - return this.free; - } - - @Override - public String toString() { - return asString(true, true, null); - } - /** * Do not use the builder, use the static factory methods. Only use the builder if you need to * override the {@link TestAccessEgress class}. @@ -280,43 +77,23 @@ protected static class Builder { int stop; int durationInSeconds; - int c1; - int numberOfRides = DEFAULT_NUMBER_OF_RIDES; + int generalizedCost; + int numberOfRides = ZERO; boolean stopReachedOnBoard = STOP_REACHED_ON_FOOT; - Integer opening = null; - Integer closing = null; - private boolean free = false; - private boolean closed = false; - private int timePenalty; Builder(int stop, int durationInSeconds) { this.stop = stop; this.durationInSeconds = durationInSeconds; - this.c1 = walkCost(durationInSeconds); - this.timePenalty = RaptorConstants.TIME_NOT_SET; - } - - Builder(TestAccessEgress original) { - this.free = original.free; - this.stop = original.stop; - this.durationInSeconds = original.durationInSeconds; - this.stopReachedOnBoard = original.stopReachedOnBoard; - this.c1 = original.c1; - this.numberOfRides = original.numberOfRides; - this.opening = original.opening; - this.closing = original.closing; - this.closed = original.closed; - this.timePenalty = original.timePenalty; + this.generalizedCost = walkCost(durationInSeconds); } Builder withFree() { - this.free = true; - this.durationInSeconds = 0; + this.durationInSeconds = ZERO; return this; } - Builder withCost(int cost) { - this.c1 = cost; + Builder withCost(int generalizedCost) { + this.generalizedCost = generalizedCost; return this; } @@ -330,36 +107,30 @@ Builder stopReachedOnBoard() { return this; } - Builder withTimePenalty(int timePenalty) { - this.timePenalty = timePenalty; - return this; - } - - Builder withOpeningHours(int opening, int closing) { - if (opening > closing) { - throw new IllegalStateException( - "Must open before is close. Opens at " + - TimeUtils.timeToStrCompact(opening) + - " and close at " + - TimeUtils.timeToStrCompact(closing) + - "." - ); - } - this.closed = false; - this.opening = opening; - this.closing = closing; - return this; - } - - Builder withClosed() { - this.opening = null; - this.closing = null; - this.closed = true; - return this; - } - - TestAccessEgress build() { - return new TestAccessEgress(this); + RoutingAccessEgress build() { + var stopId = "Stop:" + stop; + var lastState = new State( + new StreetLocation(stopId, Coordinates.BOSTON, I18NString.of(stopId)), + StreetSearchRequest.of().build() + ); + return new DefaultAccessEgress( + stop, + durationInSeconds, + generalizedCost, + TimeAndCost.ZERO, + lastState + ) { + // TODO - Use the domain type FlexAccessEgressAdapter here instead [if numberOfRides > 0] + @Override + public int numberOfRides() { + return numberOfRides; + } + + @Override + public boolean stopReachedOnBoard() { + return stopReachedOnBoard; + } + }; } } } diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransfer.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransfer.java index dead63d0135..700376d7f06 100644 --- a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransfer.java +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransfer.java @@ -18,10 +18,6 @@ public static TestTransfer transfer(int stop, int durationInSeconds) { return new TestTransfer(stop, durationInSeconds, walkCost(durationInSeconds)); } - public static TestTransfer transfer(int stop, int durationInSeconds, int cost) { - return new TestTransfer(stop, durationInSeconds, cost); - } - public static int walkCost(int durationInSeconds) { return walkCost(durationInSeconds, DEFAULT_WALK_RELUCTANCE); } diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransferPoint.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransferPoint.java index 8c274f779d8..9bf8c1bc17a 100644 --- a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransferPoint.java +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransferPoint.java @@ -38,10 +38,6 @@ public int getSpecificityRanking() { return 2; } - public int getStopPosition() { - return this.stopPosition; - } - public boolean matches(TestTripSchedule schedule, int stop, int stopPosition) { return this.schedule == schedule && this.stop == stop && this.stopPosition == stopPosition; } diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransitData.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransitData.java index 1cbf591c01d..63d17c8cd2d 100644 --- a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransitData.java +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTransitData.java @@ -1,9 +1,5 @@ package org.opentripplanner.raptorlegacy._data.transit; -import static org.opentripplanner.raptorlegacy._data.transit.TestRoute.route; -import static org.opentripplanner.raptorlegacy._data.transit.TestTripPattern.pattern; -import static org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule.schedule; - import java.util.ArrayList; import java.util.BitSet; import java.util.HashSet; @@ -17,8 +13,6 @@ import org.opentripplanner.raptor.api.model.RaptorStopNameResolver; import org.opentripplanner.raptor.api.model.RaptorTransfer; import org.opentripplanner.raptor.api.model.RaptorTripPattern; -import org.opentripplanner.raptor.api.request.RaptorRequestBuilder; -import org.opentripplanner.raptor.rangeraptor.SystemErrDebugLogger; import org.opentripplanner.raptor.spi.DefaultSlackProvider; import org.opentripplanner.raptor.spi.IntIterator; import org.opentripplanner.raptor.spi.RaptorConstrainedBoardingSearch; @@ -201,21 +195,6 @@ public TestRoute getRoute(int index) { return routes.get(index); } - public void debugToStdErr(RaptorRequestBuilder request, boolean dryRun) { - var debug = request.debug(); - - if (debug.stops().isEmpty()) { - debug.addStops(stopsVisited()); - } - var logger = new SystemErrDebugLogger(true, dryRun); - - debug - .stopArrivalListener(logger::stopArrivalLister) - .patternRideDebugListener(logger::patternRideLister) - .pathFilteringListener(logger::pathFilteringListener) - .logger(logger); - } - public TestTransitData withRoute(TestRoute route) { this.routes.add(route); int routeIndex = this.routes.indexOf(route); @@ -229,19 +208,6 @@ public TestTransitData withRoute(TestRoute route) { return this; } - /** - * Same as: - *

-   * withRoute(
-   *   route(pattern(routeName, stopIndexes))
-   *     .withTimetable(schedule().times(times))
-   * )
-   * 
- */ - public TestTransitData withTransit(String routeName, String times, int... stopIndexes) { - return withRoute(route(pattern(routeName, stopIndexes)).withTimetable(schedule().times(times))); - } - public TestTransitData withRoutes(TestRoute... routes) { for (TestRoute route : routes) { withRoute(route); @@ -305,15 +271,6 @@ public TestTransitData withConstrainedTransfer( return this; } - public TestTransitData withStopBoardAlightTransferCost(int stop, int boardAlightTransferCost) { - stopBoardAlightTransferCosts[stop] = boardAlightTransferCost; - return this; - } - - public GeneralizedCostParametersBuilder mcCostParamsBuilder() { - return costParamsBuilder; - } - public ConstrainedTransfer findConstrainedTransfer( TestTripSchedule fromTrip, int fromStop, @@ -372,14 +329,4 @@ private void expandNumOfStops(int stopIndex) { routeIndexesByStopIndex.add(new HashSet<>()); } } - - private List stopsVisited() { - final List stops = new ArrayList<>(); - for (int i = 0; i < routeIndexesByStopIndex.size(); i++) { - if (!routeIndexesByStopIndex.get(i).isEmpty()) { - stops.add(i); - } - } - return stops; - } } diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTripPattern.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTripPattern.java index f6d9aace021..b8367e0225d 100644 --- a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTripPattern.java +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTripPattern.java @@ -65,11 +65,6 @@ TestTripPattern withPatternIndex(int index) { return this; } - public TestTripPattern withPriorityGroup(int priorityGroupId) { - this.priorityGroupId = priorityGroupId; - return this; - } - public TestTripPattern withRoute(Route route) { this.route = route; return this; @@ -106,10 +101,6 @@ public void restrictions(String codes) { } } - public String getName() { - return name; - } - @Override public int stopIndex(int stopPositionInPattern) { return stopIndexes[stopPositionInPattern]; diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTripSchedule.java b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTripSchedule.java index 0ef437cb3d0..1b0441b64f8 100644 --- a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTripSchedule.java +++ b/application/src/test/java/org/opentripplanner/raptorlegacy/_data/transit/TestTripSchedule.java @@ -4,14 +4,12 @@ import java.time.LocalDate; import java.util.Arrays; -import java.util.stream.IntStream; import org.opentripplanner.raptor.api.model.RaptorTripSchedule; import org.opentripplanner.routing.algorithm.raptoradapter.api.DefaultTripPattern; import org.opentripplanner.routing.algorithm.raptoradapter.transit.TripSchedule; import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.timetable.TripTimes; -import org.opentripplanner.utils.lang.IntUtils; import org.opentripplanner.utils.time.TimeUtils; import org.opentripplanner.utils.tostring.ToStringBuilder; @@ -100,10 +98,6 @@ public Accessibility wheelchairBoarding() { return wheelchairBoarding; } - public int size() { - return arrivalTimes.length; - } - @Override public String toString() { if (Arrays.equals(arrivalTimes, departureTimes)) { @@ -155,18 +149,6 @@ public TestTripSchedule.Builder originalPattern(TripPattern pattern) { return this; } - public TestTripSchedule.Builder copy() { - var b = new TestTripSchedule.Builder(); - b.pattern = pattern; - b.arrivalTimes = arrivalTimes; - b.departureTimes = departureTimes; - b.arrivalDepartureOffset = arrivalDepartureOffset; - b.transitReluctanceIndex = transitReluctanceIndex; - b.wheelchairBoarding = wheelchairBoarding; - b.originalPattern = originalPattern; - return b; - } - public TestTripSchedule.Builder pattern(String name, int... stops) { return pattern(TestTripPattern.pattern(name, stops)); } @@ -216,26 +198,6 @@ public TestTripSchedule.Builder arrDepOffset(int arrivalDepartureOffset) { return this; } - /** - * Shift all arrival/departure times by the given {@code offset}. Be careful, this - * method change the builder instance, use {@link #copy()} if you need the original. - *

- * Offset unit is seconds. - */ - public TestTripSchedule.Builder shiftTimes(int offset) { - if (arrivalTimes == departureTimes) { - arrivalTimes = departureTimes = IntUtils.shiftArray(offset, arrivalTimes); - } else { - if (arrivalTimes != null) { - arrivalTimes = IntUtils.shiftArray(offset, arrivalTimes); - } - if (departureTimes != null) { - departureTimes = IntUtils.shiftArray(offset, departureTimes); - } - } - return this; - } - /** * Set the transit-reluctance-index. *

@@ -251,13 +213,6 @@ public TestTripSchedule.Builder wheelchairBoarding(Accessibility wcb) { return this; } - public TestTripSchedule.Builder[] repeat(int nTimes, int everySeconds) { - return IntStream - .range(0, nTimes) - .mapToObj(i -> copy().shiftTimes(i * everySeconds)) - .toArray(Builder[]::new); - } - public TestTripSchedule build() { if (arrivalTimes == null) { arrivalTimes = copyWithOffset(departureTimes, -arrivalDepartureOffset); diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultAccessEgressTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultAccessEgressTest.java index 0fcb7c8cea3..76b539c2726 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultAccessEgressTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/DefaultAccessEgressTest.java @@ -31,8 +31,7 @@ void canNotAddPenaltyTwice() { @Test void durationInSeconds() { - // TODO - The value is ? - int expected = 118215; + int expected = (int) LAST_STATE.getElapsedTimeSeconds(); assertEquals(expected, subject.durationInSeconds()); assertEquals(expected, subjectWithPenalty.durationInSeconds()); } @@ -102,13 +101,6 @@ void containsModeWalkOnly() { assertFalse(subject.isWalkOnly()); } - @Test - void hasPenalty() { - assertFalse(subject.hasPenalty()); - assertFalse(subject.withPenalty(TimeAndCost.ZERO).hasPenalty()); - assertTrue(subjectWithPenalty.hasPenalty()); - } - @Test void penalty() { assertEquals(TimeAndCost.ZERO, subject.penalty()); diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultCostCalculatorTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultCostCalculatorTest.java index ad31b250046..ef10296a3ef 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultCostCalculatorTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/raptoradapter/transit/cost/DefaultCostCalculatorTest.java @@ -121,12 +121,9 @@ public void testCostEgressWithRides() { // Should be generalized cost plus transfer cost var GENERALIZED_COST = 100; - var DESIRED_COST = GENERALIZED_COST + TRANSFER_COST_SEC * 100; + var DESIRED_COST = GENERALIZED_COST + RaptorCostConverter.toRaptorCost(TRANSFER_COST_SEC); - // Should be the same on all stop indexes - var t1 = TestAccessEgress.flex(0, 15, 1, GENERALIZED_COST); - assertEquals(DESIRED_COST, subject.costEgress(t1)); - var t2 = TestAccessEgress.flex(1, 15, 1, GENERALIZED_COST); - assertEquals(DESIRED_COST, subject.costEgress(t2)); + var egress = TestAccessEgress.flex(0, 15, 1, GENERALIZED_COST); + assertEquals(DESIRED_COST, subject.costEgress(egress)); } } diff --git a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/BasicPathTestCase.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/BasicPathTestCase.java similarity index 63% rename from application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/BasicPathTestCase.java rename to application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/BasicPathTestCase.java index 0130625784b..02bf8c522c2 100644 --- a/application/src/test/java/org/opentripplanner/raptorlegacy/_data/stoparrival/BasicPathTestCase.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/BasicPathTestCase.java @@ -1,14 +1,8 @@ -package org.opentripplanner.raptorlegacy._data.stoparrival; +package org.opentripplanner.routing.algorithm.transferoptimization; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.model.transfer.TransferConstraint.REGULAR_TRANSFER; import static org.opentripplanner.raptor.api.model.RaptorCostConverter.toRaptorCost; -import static org.opentripplanner.utils.time.DurationUtils.durationToStr; import static org.opentripplanner.utils.time.TimeUtils.time; -import java.util.Arrays; -import java.util.List; -import org.junit.jupiter.api.Test; import org.opentripplanner.raptor.api.model.RaptorAccessEgress; import org.opentripplanner.raptor.api.model.RaptorConstrainedTransfer; import org.opentripplanner.raptor.api.model.RaptorTransfer; @@ -18,11 +12,7 @@ import org.opentripplanner.raptor.api.path.RaptorPath; import org.opentripplanner.raptor.api.path.TransferPathLeg; import org.opentripplanner.raptor.api.path.TransitPathLeg; -import org.opentripplanner.raptor.api.view.ArrivalView; import org.opentripplanner.raptor.path.Path; -import org.opentripplanner.raptor.rangeraptor.internalapi.WorkerLifeCycle; -import org.opentripplanner.raptor.rangeraptor.lifecycle.LifeCycleSubscriptions; -import org.opentripplanner.raptor.rangeraptor.path.DestinationArrival; import org.opentripplanner.raptor.spi.RaptorCostCalculator; import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; import org.opentripplanner.raptorlegacy._data.transit.TestAccessEgress; @@ -110,7 +100,6 @@ public class BasicPathTestCase implements RaptorTestConstants { ACCESS_DURATION ); public static final int ACCESS_C1 = ACCESS_TRANSFER.c1(); - public static final int ACCESS_C2 = 0; // Trip 1 (A ~ BUS L11 10:04 10:35 ~ B) public static final int L11_START = time("10:04"); @@ -121,7 +110,6 @@ public class BasicPathTestCase implements RaptorTestConstants { STOP_C1S[STOP_A] + STOP_C1S[STOP_B] + toRaptorCost(BOARD_C1_SEC + WAIT_RELUCTANCE * L11_WAIT_DURATION + L11_DURATION); - public static final int LINE_11_C2 = 2; // Transfers (B ~ Walk 3m45s ~ C) private static final int TX_START = time("10:35:15"); @@ -129,7 +117,6 @@ public class BasicPathTestCase implements RaptorTestConstants { public static final int TX_DURATION = TX_END - TX_START; public static final RaptorTransfer TX_TRANSFER = TestTransfer.transfer(STOP_C, TX_DURATION); public static final int TX_C1 = TX_TRANSFER.c1(); - public static final int TX_C3 = 3; // Trip 2 (C ~ BUS L21 11:00 11:23 ~ D) public static final int L21_START = time("11:00"); @@ -142,7 +129,6 @@ public class BasicPathTestCase implements RaptorTestConstants { toRaptorCost( BOARD_C1_SEC + TRANSFER_C1_SEC + WAIT_RELUCTANCE * L21_WAIT_DURATION + L21_DURATION ); - public static final int LINE_21_C2 = 5; // Trip 3 (D ~ BUS L31 11:40 11:52 ~ E) public static final int L31_START = time("11:40"); @@ -155,7 +141,6 @@ public class BasicPathTestCase implements RaptorTestConstants { toRaptorCost( BOARD_C1_SEC + TRANSFER_C1_SEC + WAIT_RELUCTANCE * L31_WAIT_DURATION + L31_DURATION ); - public static final int LINE_31_C2 = 6; // Egress (E ~ Walk 7m45s ~ ) public static final int EGRESS_START = time("11:52:15"); @@ -166,9 +151,6 @@ public class BasicPathTestCase implements RaptorTestConstants { EGRESS_DURATION ); public static final int EGRESS_C1 = EGRESS_TRANSFER.c1(); - public static final int EGRESS_C2 = 7; - - public static final int TRIP_DURATION = EGRESS_END - ACCESS_START; private static final RaptorAccessEgress ACCESS = TestAccessEgress.walk( STOP_A, @@ -222,62 +204,6 @@ public class BasicPathTestCase implements RaptorTestConstants { public static final int TOTAL_C1 = ACCESS_C1 + LINE_11_C1 + TX_C1 + LINE_21_C1 + LINE_31_C1 + EGRESS_C1; - /** Wait time between trip L11 and L21 including slack */ - public static final int WAIT_TIME_L11_L21 = L21_START - L11_END - TX_DURATION; - - /** Wait time between trip L21 and L31 including slack */ - public static final int WAIT_TIME_L21_L31 = L31_START - L21_END; - - public static WorkerLifeCycle lifeCycle() { - return new LifeCycleSubscriptions(); - } - - public static DestinationArrival basicTripByForwardSearch() { - ArrivalView prevArrival, egress; - prevArrival = TestArrivals.access(STOP_A, ACCESS_START, ACCESS_END, ACCESS_C1, ACCESS_C2); - prevArrival = TestArrivals.bus(1, STOP_B, L11_END, LINE_11_C1, LINE_11_C2, TRIP_1, prevArrival); - prevArrival = TestArrivals.transfer(1, STOP_C, TX_START, TX_END, TX_C1, prevArrival); - prevArrival = TestArrivals.bus(2, STOP_D, L21_END, LINE_21_C1, LINE_21_C2, TRIP_2, prevArrival); - prevArrival = TestArrivals.bus(3, STOP_E, L31_END, LINE_31_C1, LINE_31_C2, TRIP_3, prevArrival); - egress = TestArrivals.egress(EGRESS_START, EGRESS_END, EGRESS_C1, EGRESS_C2, prevArrival); - return new DestinationArrival<>( - egress.egressPath().egress(), - egress.previous(), - egress.arrivalTime(), - egress.egressPath().egress().c1(), - egress.c2() - ); - } - - /** - * This is the same itinerary as {@link #basicTripByForwardSearch()}, as found by a reverse - * search: - */ - public static DestinationArrival basicTripByReverseSearch() { - ArrivalView nextArrival, egress; - nextArrival = TestArrivals.access(STOP_E, EGRESS_END, EGRESS_START, EGRESS_C1, EGRESS_C2); - // Board slack is subtracted from the arrival time to get the latest possible - nextArrival = - TestArrivals.bus(1, STOP_D, L31_START, LINE_31_C1, LINE_31_C2, TRIP_3, nextArrival); - nextArrival = - TestArrivals.bus(2, STOP_C, L21_START, LINE_21_C1, LINE_21_C2, TRIP_2, nextArrival); - nextArrival = TestArrivals.transfer(2, STOP_B, TX_END, TX_START, TX_C1, nextArrival); - nextArrival = - TestArrivals.bus(3, STOP_A, L11_START, LINE_11_C1, LINE_11_C2, TRIP_1, nextArrival); - egress = TestArrivals.egress(ACCESS_END, ACCESS_START, ACCESS_C1, ACCESS_C2, nextArrival); - return new DestinationArrival<>( - egress.egressPath().egress(), - egress.previous(), - egress.arrivalTime(), - egress.egressPath().egress().c1(), - egress.c2() - ); - } - - /** - * Both {@link #basicTripByForwardSearch()} and {@link #basicTripByReverseSearch()} should return - * the same trip, here returned as a path. - */ public static RaptorPath basicTripAsPath() { PathLeg leg6 = new EgressPathLeg<>( EGRESS, @@ -364,99 +290,4 @@ public static RaptorPath flexTripAsPath() { ); return new Path<>(RAPTOR_ITERATION_START_TIME, leg1, TOTAL_C1, C2); } - - public static List basicTripStops() { - return Arrays.asList(STOP_A, STOP_B, STOP_C, STOP_D, STOP_E); - } - - @Test - public void testSetup() { - // Assert test data is configured correct - assertEquals(ACCESS_END + BOARD_SLACK, L11_START); - assertEquals(BOARD_SLACK + ALIGHT_SLACK, L11_WAIT_DURATION); - assertEquals(L31_END + ALIGHT_SLACK, EGRESS_START); - assertEquals( - durationToStr(TRIP_DURATION), - durationToStr( - ACCESS_DURATION + - L11_DURATION + - L11_WAIT_DURATION + - TX_DURATION + - L21_DURATION + - L21_WAIT_DURATION + - L31_DURATION + - L31_WAIT_DURATION + - EGRESS_DURATION - ), - "Access: " + - durationToStr(ACCESS_DURATION) + - ", Line 11: " + - durationToStr(L11_DURATION) + - " (wait " + - durationToStr(L11_WAIT_DURATION) + - ")" + - ", Tx: " + - durationToStr(TX_DURATION) + - ", Line 21: " + - durationToStr(L21_DURATION) + - " (wait " + - durationToStr(L21_WAIT_DURATION) + - ")" + - ", Line 31: " + - durationToStr(L31_DURATION) + - " (wait " + - durationToStr(L31_WAIT_DURATION) + - ")" + - ", Egress: " + - durationToStr(EGRESS_DURATION) - ); - - // The calculator is not under test here, so we assert everything is as expected - assertEquals( - LINE_11_C1, - transitArrivalCost(ACCESS_END, TRIP_1, STOP_A, L11_START, STOP_B, L11_END) - ); - assertEquals( - LINE_21_C1, - transitArrivalCost(TX_END, TRIP_2, STOP_C, L21_START, STOP_D, L21_END) - ); - assertEquals( - LINE_31_C1, - transitArrivalCost(L21_END + ALIGHT_SLACK, TRIP_3, STOP_D, L31_START, STOP_E, L31_END) - ); - - assertEquals(BASIC_PATH_AS_STRING, basicTripAsPath().toString(this::stopIndexToName)); - - assertEquals( - BASIC_PATH_AS_DETAILED_STRING, - basicTripAsPath().toStringDetailed(this::stopIndexToName) - ); - } - - private static int transitArrivalCost( - int prevArrivalTime, - TestTripSchedule trip, - int boardStop, - int boardTime, - int alightStop, - int alightTime - ) { - boolean firstTransit = TRIP_1 == trip; - int boardCost = C1_CALCULATOR.boardingCost( - firstTransit, - prevArrivalTime, - boardStop, - boardTime, - trip, - REGULAR_TRANSFER - ); - - return C1_CALCULATOR.transitArrivalCost( - boardCost, - ALIGHT_SLACK, - alightTime - boardTime, - trip, - alightStop - ); - } } diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/api/OptimizedPathTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/api/OptimizedPathTest.java index bc01a082740..4837d8e9ac8 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/api/OptimizedPathTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/api/OptimizedPathTest.java @@ -6,7 +6,7 @@ import org.junit.jupiter.api.Test; import org.opentripplanner.raptor.api.model.RaptorValueFormatter; import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; -import org.opentripplanner.raptorlegacy._data.stoparrival.BasicPathTestCase; +import org.opentripplanner.routing.algorithm.transferoptimization.BasicPathTestCase; class OptimizedPathTest implements RaptorTestConstants { diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/MinSafeTransferTimeCalculatorTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/MinSafeTransferTimeCalculatorTest.java index d5d8f7c7c62..1cd9c8f139d 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/MinSafeTransferTimeCalculatorTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/MinSafeTransferTimeCalculatorTest.java @@ -1,7 +1,6 @@ package org.opentripplanner.routing.algorithm.transferoptimization.model; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.raptorlegacy._data.stoparrival.BasicPathTestCase.C1_CALCULATOR; import static org.opentripplanner.routing.algorithm.transferoptimization.model.MinSafeTransferTimeCalculator.bound; import static org.opentripplanner.utils.time.TimeUtils.time; @@ -10,15 +9,16 @@ import org.opentripplanner.raptor.api.path.RaptorPath; import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; import org.opentripplanner.raptorlegacy._data.api.TestPathBuilder; -import org.opentripplanner.raptorlegacy._data.stoparrival.BasicPathTestCase; import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; import org.opentripplanner.utils.time.DurationUtils; public class MinSafeTransferTimeCalculatorTest implements RaptorTestConstants { private static final int D2m = DurationUtils.durationInSeconds("2m"); - private static final int TRANSIT_TIME = 2000 - (BOARD_SLACK + ALIGHT_SLACK); - private static final TestPathBuilder PATH_BUILDER = new TestPathBuilder(C1_CALCULATOR); + private static final int D32m20s = DurationUtils.durationInSeconds("32m20s"); + private static final int TRANSIT_TIME = D32m20s; + + private static final TestPathBuilder PATH_BUILDER = new TestPathBuilder(COST_CALCULATOR); private final MinSafeTransferTimeCalculator subject = new MinSafeTransferTimeCalculator<>( SLACK_PROVIDER @@ -27,7 +27,14 @@ public class MinSafeTransferTimeCalculatorTest implements RaptorTestConstants { .access(time("10:00:15"), STOP_A, D2m) .bus("L11", time("10:03"), TRANSIT_TIME, STOP_B) .egress(D2m); - RaptorPath path_3_bus_legs = BasicPathTestCase.basicTripAsPath(); + + RaptorPath path_3_bus_legs = PATH_BUILDER + .access(time("10:00:15"), STOP_A, D2m) + .bus("L1", time("10:03"), TRANSIT_TIME, STOP_B) + .walk(D2m, STOP_C) + .bus("L2", time("10:45"), TRANSIT_TIME, STOP_D) + .bus("L3", time("11:30"), TRANSIT_TIME, STOP_E) + .egress(D2m); @Test public void testMinSafeTransferTimeOneTransit() { @@ -36,7 +43,7 @@ public void testMinSafeTransferTimeOneTransit() { @Test public void testMinSafeTransferTimeThreeTransits() { - assertEquals(276, subject.minSafeTransferTime(List.of(path_3_bus_legs))); + assertEquals(400, subject.minSafeTransferTime(List.of(path_3_bus_legs))); } @Test diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTailTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTailTest.java index 505b6581000..f43daf1fbc9 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTailTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/OptimizedPathTailTest.java @@ -7,8 +7,8 @@ import org.opentripplanner.raptor.api.path.RaptorPath; import org.opentripplanner.raptor.api.path.TransitPathLeg; import org.opentripplanner.raptorlegacy._data.RaptorTestConstants; -import org.opentripplanner.raptorlegacy._data.stoparrival.BasicPathTestCase; import org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule; +import org.opentripplanner.routing.algorithm.transferoptimization.BasicPathTestCase; import org.opentripplanner.routing.algorithm.transferoptimization.services.TestTransferBuilder; class OptimizedPathTailTest implements RaptorTestConstants { diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/costfilter/MinCostPathTailFilterTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/costfilter/MinCostPathTailFilterTest.java index e32559c2dad..d57f949a13a 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/costfilter/MinCostPathTailFilterTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/model/costfilter/MinCostPathTailFilterTest.java @@ -1,7 +1,6 @@ package org.opentripplanner.routing.algorithm.transferoptimization.model.costfilter; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.raptorlegacy._data.stoparrival.BasicPathTestCase.C1_CALCULATOR; import java.util.List; import java.util.Objects; @@ -80,7 +79,7 @@ static class A extends OptimizedPathTail { public final int y; private A(String name, int x, int y) { - super(SLACK_PROVIDER, C1_CALCULATOR, T00_00, WAIT_TIME_CALC, null, 0.0, null); + super(SLACK_PROVIDER, COST_CALCULATOR, T00_00, WAIT_TIME_CALC, null, 0.0, null); this.name = name; this.x = x; this.y = y; diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGeneratorTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGeneratorTest.java index 4e1d89c6b49..640d7e53a64 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGeneratorTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransferGeneratorTest.java @@ -2,7 +2,6 @@ import static java.time.Duration.ofMinutes; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.opentripplanner.raptorlegacy._data.stoparrival.BasicPathTestCase.C1_CALCULATOR; import static org.opentripplanner.raptorlegacy._data.transit.TestRoute.route; import static org.opentripplanner.raptorlegacy._data.transit.TestTripSchedule.schedule; @@ -46,7 +45,7 @@ public class TransferGeneratorTest implements RaptorTestConstants { ALIGHT_SLACK ); - private final TestPathBuilder pathBuilder = new TestPathBuilder(SLACK_PROVIDER, C1_CALCULATOR); + private final TestPathBuilder pathBuilder = new TestPathBuilder(SLACK_PROVIDER, COST_CALCULATOR); private final TestTransitData data = new TestTransitData().withSlackProvider(SLACK_PROVIDER); diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransitPathLegSelectorTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransitPathLegSelectorTest.java index 5ca18f63cb9..e3b95bb07a1 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransitPathLegSelectorTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/transferoptimization/services/TransitPathLegSelectorTest.java @@ -116,7 +116,7 @@ private static String firstRide(Collection c) { } private TransitPathLeg transitLeg(int egressStop) { - TestAccessEgress walk = TestAccessEgress.walk(egressStop, EGRESS_END - EGRESS_START); + var walk = TestAccessEgress.walk(egressStop, EGRESS_END - EGRESS_START); var egress = new EgressPathLeg(walk, EGRESS_START, EGRESS_END, walk.c1()); int toTime = TRIP.arrival(TRIP.findArrivalStopPosition(Integer.MAX_VALUE, egressStop)); int cost = 100 * (STOP_TIME_THREE - STOP_TIME_ONE); diff --git a/raptor/src/main/java/org/opentripplanner/raptor/api/model/AbstractAccessEgressDecorator.java b/raptor/src/main/java/org/opentripplanner/raptor/api/model/AbstractAccessEgressDecorator.java index eb1a388f91c..aaf1b2f4cde 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/api/model/AbstractAccessEgressDecorator.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/model/AbstractAccessEgressDecorator.java @@ -1,6 +1,8 @@ package org.opentripplanner.raptor.api.model; +import java.time.Duration; import java.util.Objects; +import java.util.Optional; import javax.annotation.Nullable; /** @@ -16,6 +18,13 @@ public AbstractAccessEgressDecorator(RaptorAccessEgress delegate) { this.delegate = delegate; } + public static RaptorAccessEgress accessEgressWithExtraSlack( + RaptorAccessEgress delegate, + Duration slack + ) { + return accessEgressWithExtraSlack(delegate, (int) slack.toSeconds()); + } + public static RaptorAccessEgress accessEgressWithExtraSlack( RaptorAccessEgress delegate, int slack @@ -28,6 +37,18 @@ public int durationInSeconds() { }; } + @SuppressWarnings({ "ReassignedVariable", "unchecked" }) + static Optional findType(RaptorAccessEgress it, Class type) { + while (!type.isAssignableFrom(it.getClass())) { + if (it instanceof AbstractAccessEgressDecorator d) { + it = d.delegate(); + } else { + throw new IllegalStateException("Unexpected type: " + type + ". Type not found in:" + it); + } + } + return Optional.of((T) it); + } + protected RaptorAccessEgress delegate() { return delegate; } diff --git a/raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorAccessEgress.java b/raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorAccessEgress.java index f970254dcc8..4facce0577c 100644 --- a/raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorAccessEgress.java +++ b/raptor/src/main/java/org/opentripplanner/raptor/api/model/RaptorAccessEgress.java @@ -3,6 +3,7 @@ import static org.opentripplanner.raptor.api.model.RaptorConstants.TIME_NOT_SET; import java.time.temporal.ChronoUnit; +import java.util.Optional; import javax.annotation.Nullable; import org.opentripplanner.utils.time.DurationUtils; import org.opentripplanner.utils.time.TimeUtils; @@ -13,6 +14,26 @@ * to Raptor - all these are the same thing. */ public interface RaptorAccessEgress { + /** + * Raptor may decorate access/egress passed into Raptor. Use this method to get the original + * instance of a given {@code type} type passed into Raptor. The first element matching the + * given {@code type} in the chain of delegates (see {@link AbstractAccessEgressDecorator}) is + * returned. + *

+ * This method is primarily for use outside Raptor to get the base access-egress instant to + * access the EXTENDED state of the base type - state not part of the Raptor interface. This is + * useful in the caller to get access to additional information stored in the base type. + *

+ * Be careful, calling methods part of the {@link RaptorAccessEgress} interface on the returned + * value will no longer be decorated - not be the value used by Raptor. + * + * @throws IllegalStateException if the given {@code parentType} does not exist in the chain + * of delegates including the first and last element. + */ + default Optional findOriginal(Class type) { + return AbstractAccessEgressDecorator.findType(this, type); + } + /** *

    *
  • Access: The first stop in the journey, where the access path just arrived at. diff --git a/raptor/src/test/java/org/opentripplanner/raptor/api/model/AbstractAccessEgressDecoratorTest.java b/raptor/src/test/java/org/opentripplanner/raptor/api/model/AbstractAccessEgressDecoratorTest.java new file mode 100644 index 00000000000..b5de21a1364 --- /dev/null +++ b/raptor/src/test/java/org/opentripplanner/raptor/api/model/AbstractAccessEgressDecoratorTest.java @@ -0,0 +1,123 @@ +package org.opentripplanner.raptor.api.model; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.time.Duration; +import org.junit.jupiter.api.Test; +import org.opentripplanner.raptor._data.transit.TestAccessEgress; + +class AbstractAccessEgressDecoratorTest { + + private static final int DURATION = 600; + private static final int SLACK = 60; + private static final int STOP = 7; + private static final TestAccessEgress DELEGATE = TestAccessEgress.walk(STOP, DURATION); + private static final TestAccessEgress DELEGATE_W_OPENING_HOURS = DELEGATE.openingHours( + "10:00", + "10:35" + ); + + private final RaptorAccessEgress subject = AbstractAccessEgressDecorator.accessEgressWithExtraSlack( + DELEGATE, + SLACK + ); + private final RaptorAccessEgress subjectWOpeningHours = AbstractAccessEgressDecorator.accessEgressWithExtraSlack( + DELEGATE_W_OPENING_HOURS, + SLACK + ); + + private AbstractAccessEgressDecorator subjectCast() { + return (AbstractAccessEgressDecorator) subject; + } + + @Test + void resolveDelegate() { + assertEquals( + DELEGATE, + AbstractAccessEgressDecorator.findType(subject, TestAccessEgress.class).orElseThrow() + ); + assertEquals( + DELEGATE, + AbstractAccessEgressDecorator.findType(DELEGATE, TestAccessEgress.class).orElseThrow() + ); + } + + @Test + void createAccessEgressWithExtraSlackFromDuration() { + var fromDuration = AbstractAccessEgressDecorator.accessEgressWithExtraSlack( + DELEGATE, + Duration.ofSeconds(SLACK) + ); + assertEquals(subject.durationInSeconds(), fromDuration.durationInSeconds()); + } + + @Test + void delegate() { + assertEquals(DELEGATE, subjectCast().delegate()); + } + + @Test + void stop() { + assertEquals(STOP, subject.stop()); + assertEquals(DELEGATE.stop(), subject.stop()); + } + + @Test + void c1() { + assertEquals(DELEGATE.c1(), subject.c1()); + } + + @Test + void durationInSeconds() { + assertEquals(DELEGATE.durationInSeconds() + SLACK, subject.durationInSeconds()); + } + + @Test + void timePenalty() {} + + @Test + void hasTimePenalty() { + assertFalse(subject.hasTimePenalty()); + } + + @Test + void earliestDepartureTime() { + assertEquals(100, subject.earliestDepartureTime(100)); + } + + @Test + void latestArrivalTime() { + assertEquals(100, subject.latestArrivalTime(100)); + } + + @Test + void hasOpeningHours() { + assertFalse(subject.hasOpeningHours()); + assertTrue(subjectWOpeningHours.hasOpeningHours()); + } + + @Test + void openingHoursToString() { + assertNull(subject.openingHoursToString()); + assertEquals("Open(10:00 10:35)", subjectWOpeningHours.openingHoursToString()); + } + + @Test + void numberOfRides() { + assertEquals(0, subject.numberOfRides()); + } + + @Test + void hasRides() { + assertFalse(subject.hasRides()); + } + + @Test + void testToString() { + assertEquals("Walk 10m C₁1_200 ~ 7", subject.toString()); + assertEquals("Walk 10m C₁1_200 Open(10:00 10:35) ~ 7", subjectWOpeningHours.toString()); + } +}