Skip to content

Commit b022e57

Browse files
committed
Merge remote-tracking branch 'upstream/dev-2.x' into feature/modified-gtfs-rt-patterns
2 parents d7df30d + 6d407ec commit b022e57

302 files changed

Lines changed: 8056 additions & 2370 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/cibuild.yml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,8 @@ jobs:
5050
# https://github.com/actions/runner-images/issues/1499
5151
# we set nodePath and npmPath to skip downloading the node binary, which frequently times out
5252
run: |
53-
mvn spotless:check
5453
mvn jacoco:prepare-agent test jacoco:report -P prettierCheck -Dprettier.nodePath=node -Dprettier.npmPath=npm
55-
mvn package -Dmaven.test.skip -P prettierSkip
54+
mvn package -Dmaven.test.skip -P prettierSkip,checkstyleSkip
5655
5756
- name: Send coverage data to codecov.io
5857
if: github.repository_owner == 'opentripplanner'
@@ -73,7 +72,7 @@ jobs:
7372
if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/dev-1.x' || github.ref == 'refs/heads/dev-2.x')
7473
env:
7574
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
76-
run: mvn deploy --settings maven-settings.xml -DskipTests -DGITHUB_REPOSITORY=$GITHUB_REPOSITORY -P prettierSkip -P deployGitHub
75+
run: mvn deploy --settings maven-settings.xml -DskipTests -DGITHUB_REPOSITORY=$GITHUB_REPOSITORY -P prettierSkip,checkstyleSkip,deployGitHub
7776

7877
build-windows:
7978
timeout-minutes: 20
@@ -91,7 +90,7 @@ jobs:
9190
- name: Configure Windows Pagefile
9291
uses: al-cheb/configure-pagefile-action@v1.4
9392
- name: Run tests
94-
run: mvn test -P prettierSkip
93+
run: mvn test -P prettierSkip,checkstyleSkip
9594

9695
docs:
9796
if: github.repository_owner == 'opentripplanner'
@@ -204,7 +203,7 @@ jobs:
204203
distribution: temurin
205204
cache: maven
206205
- name: Compile Java code
207-
run: mvn compile -DskipTests -P prettierSkip
206+
run: mvn compile -DskipTests -P prettierSkip,checkstyleSkip
208207

209208
container-image:
210209
if: github.repository_owner == 'opentripplanner' && github.event_name == 'push' && (github.ref == 'refs/heads/dev-2.x' || github.ref == 'refs/heads/master')
@@ -247,6 +246,6 @@ jobs:
247246
echo "Maven version ${version_with_snapshot} contains SNAPSHOT, adding date to container image tag"
248247
fi
249248
250-
MAVEN_SKIP_ARGS="-P prettierSkip -Dmaven.test.skip=true -Dmaven.source.skip=true"
249+
MAVEN_SKIP_ARGS="-P prettierSkip,checkstyleSkip -Dmaven.test.skip=true -Dmaven.source.skip=true"
251250
252251
mvn $MAVEN_SKIP_ARGS package com.google.cloud.tools:jib-maven-plugin:build -Djib.to.tags=latest,$image_version

.github/workflows/performance-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ jobs:
8484
if: matrix.profile == 'core' || github.ref == 'refs/heads/dev-2.x'
8585
env:
8686
MAVEN_OPTS: "-Dmaven.repo.local=/home/lenni/.m2/repository/"
87-
run: mvn -DskipTests --batch-mode install -P prettierSkip
87+
run: mvn -DskipTests --batch-mode install -P prettierSkip,checkstyleSkip
8888

8989
- name: Build graph
9090
if: matrix.profile == 'core' || github.ref == 'refs/heads/dev-2.x'

DEVELOPMENT_DECISION_RECORDS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ Document API and configuration parameters.
4848

4949
## Respect-Codestyle
5050

51-
OTP uses prettier to format code. For more information on code style see the
52-
[Codestyle](doc/dev/decisionrecords/Codestyle.md) document.
51+
OTP uses Prettier to format code and Checkstyle to check for other code style issues.
52+
For more information on code style see the [Codestyle](doc/dev/decisionrecords/Codestyle.md) document.
5353

5454

5555
## Use-Object-Oriented-Principals

application/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
<dependency>
6262
<groupId>net.logstash.logback</groupId>
6363
<artifactId>logstash-logback-encoder</artifactId>
64-
<version>8.1</version>
64+
<version>9.0</version>
6565
</dependency>
6666

6767
<!-- dependency injection -->
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package org.opentripplanner.ext.fares.impl.gtfs;
2+
3+
import static com.google.common.truth.Truth.assertThat;
4+
import static org.opentripplanner.ext.fares.model.FareTransferRule.UNLIMITED_TRANSFERS;
5+
import static org.opentripplanner.ext.fares.model.TimeLimitType.DEPARTURE_TO_ARRIVAL;
6+
import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary;
7+
import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id;
8+
import static org.opentripplanner.utils.time.TimeUtils.time;
9+
10+
import com.google.common.collect.ImmutableMultimap;
11+
import java.time.Duration;
12+
import java.util.List;
13+
import org.junit.jupiter.api.Test;
14+
import org.opentripplanner.ext.fares.impl._support.FareTestConstants;
15+
import org.opentripplanner.ext.fares.model.FareLegRule;
16+
import org.opentripplanner.ext.fares.model.FareTransferRule;
17+
import org.opentripplanner.model.fare.FareOffer;
18+
import org.opentripplanner.model.plan.PlanTestConstants;
19+
import org.opentripplanner.transit.model.framework.FeedScopedId;
20+
21+
class DepartureToArrivalTimeLimitTest implements PlanTestConstants, FareTestConstants {
22+
23+
private static final FeedScopedId LEG_GROUP = id("leg-group-a");
24+
25+
private static final GtfsFaresV2Service SERVICE = new GtfsFaresV2Service(
26+
List.of(FareLegRule.of(id("r1"), FARE_PRODUCT_A).withLegGroupId(LEG_GROUP).build()),
27+
List.of(
28+
FareTransferRule.of()
29+
.withId(id("transfer"))
30+
.withFromLegGroup(LEG_GROUP)
31+
.withToLegGroup(LEG_GROUP)
32+
.withTransferCount(UNLIMITED_TRANSFERS)
33+
.withFareProducts(List.of(TRANSFER_1))
34+
.withTimeLimit(DEPARTURE_TO_ARRIVAL, Duration.ofMinutes(10))
35+
.build()
36+
),
37+
ImmutableMultimap.of()
38+
);
39+
40+
@Test
41+
void twoLegsAboveLimit() {
42+
var i1 = newItinerary(A, time("10:00"))
43+
.bus(1, time("10:00"), time("10:11"), B)
44+
.bus(2, time("10:12"), time("10:22"), C)
45+
.build();
46+
47+
var result = SERVICE.calculateFares(i1);
48+
49+
assertThat(result.itineraryProducts()).isEmpty();
50+
51+
var first = i1.legs().getFirst();
52+
var last = i1.legs().getLast();
53+
assertThat(result.offersForLeg(first)).containsExactly(
54+
FareOffer.of(first.startTime(), FARE_PRODUCT_A)
55+
);
56+
assertThat(result.offersForLeg(last)).containsExactly(
57+
FareOffer.of(last.startTime(), FARE_PRODUCT_A)
58+
);
59+
}
60+
61+
@Test
62+
void twoLegsBelowLimit() {
63+
var i1 = newItinerary(A, time("10:00"))
64+
.bus(1, time("10:00"), time("10:03"), B)
65+
.bus(2, time("10:03"), time("10:06"), C)
66+
.build();
67+
68+
var result = SERVICE.calculateFares(i1);
69+
70+
assertThat(result.itineraryProducts()).isEmpty();
71+
72+
var first = i1.legs().getFirst();
73+
var last = i1.legs().getLast();
74+
assertThat(result.offersForLeg(first)).containsExactly(
75+
FareOffer.of(first.startTime(), FARE_PRODUCT_A)
76+
);
77+
assertThat(result.offersForLeg(last)).containsExactly(
78+
FareOffer.of(last.startTime(), FARE_PRODUCT_A),
79+
FareOffer.of(first.startTime(), TRANSFER_1, List.of(FARE_PRODUCT_A))
80+
);
81+
}
82+
83+
@Test
84+
void threeLegs() {
85+
var i1 = newItinerary(A, time("10:00"))
86+
.bus(1, time("10:00"), time("10:03"), B)
87+
.bus(2, time("10:03"), time("10:06"), C)
88+
.bus(2, time("10:09"), time("10:15"), D)
89+
.build();
90+
91+
var result = SERVICE.calculateFares(i1);
92+
93+
assertThat(result.itineraryProducts()).isEmpty();
94+
95+
var first = i1.legs().getFirst();
96+
var second = i1.legs().get(1);
97+
var last = i1.legs().getLast();
98+
assertThat(result.offersForLeg(first)).containsExactly(
99+
FareOffer.of(first.startTime(), FARE_PRODUCT_A)
100+
);
101+
assertThat(result.offersForLeg(second)).containsExactly(
102+
FareOffer.of(second.startTime(), FARE_PRODUCT_A),
103+
FareOffer.of(first.startTime(), TRANSFER_1, List.of(FARE_PRODUCT_A))
104+
);
105+
assertThat(result.offersForLeg(last)).containsExactly(
106+
FareOffer.of(last.startTime(), FARE_PRODUCT_A)
107+
);
108+
}
109+
110+
@Test
111+
void fourLegs() {
112+
var i1 = newItinerary(A, time("10:00"))
113+
.bus(1, time("10:00"), time("10:03"), B)
114+
.bus(2, time("10:03"), time("10:06"), C)
115+
.bus(3, time("10:09"), time("10:15"), D)
116+
.bus(4, time("10:15"), time("10:17"), E)
117+
.build();
118+
119+
var result = SERVICE.calculateFares(i1);
120+
121+
assertThat(result.itineraryProducts()).isEmpty();
122+
123+
var first = i1.legs().getFirst();
124+
var second = i1.legs().get(1);
125+
var third = i1.legs().get(2);
126+
var last = i1.legs().getLast();
127+
assertThat(result.offersForLeg(first)).containsExactly(
128+
FareOffer.of(first.startTime(), FARE_PRODUCT_A)
129+
);
130+
assertThat(result.offersForLeg(second)).containsExactly(
131+
FareOffer.of(second.startTime(), FARE_PRODUCT_A),
132+
FareOffer.of(first.startTime(), TRANSFER_1, List.of(FARE_PRODUCT_A))
133+
);
134+
assertThat(result.offersForLeg(third)).containsExactly(
135+
FareOffer.of(third.startTime(), FARE_PRODUCT_A)
136+
);
137+
assertThat(result.offersForLeg(last)).containsExactly(
138+
FareOffer.of(last.startTime(), FARE_PRODUCT_A),
139+
FareOffer.of(third.startTime(), TRANSFER_1, List.of(FARE_PRODUCT_A))
140+
);
141+
}
142+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package org.opentripplanner.ext.fares.impl.gtfs;
2+
3+
import static com.google.common.truth.Truth.assertThat;
4+
import static org.opentripplanner.ext.fares.model.FareTransferRule.UNLIMITED_TRANSFERS;
5+
import static org.opentripplanner.ext.fares.model.TimeLimitType.DEPARTURE_TO_DEPARTURE;
6+
import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary;
7+
import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id;
8+
import static org.opentripplanner.utils.time.TimeUtils.time;
9+
10+
import com.google.common.collect.ImmutableMultimap;
11+
import java.time.Duration;
12+
import java.util.List;
13+
import org.junit.jupiter.api.Test;
14+
import org.opentripplanner.ext.fares.impl._support.FareTestConstants;
15+
import org.opentripplanner.ext.fares.model.FareLegRule;
16+
import org.opentripplanner.ext.fares.model.FareTransferRule;
17+
import org.opentripplanner.model.fare.FareOffer;
18+
import org.opentripplanner.model.plan.PlanTestConstants;
19+
import org.opentripplanner.transit.model.framework.FeedScopedId;
20+
21+
class DepartureToDepartureTimeLimitTest implements PlanTestConstants, FareTestConstants {
22+
23+
private static final FeedScopedId LEG_GROUP = id("leg-group-a");
24+
25+
private static final GtfsFaresV2Service SERVICE = new GtfsFaresV2Service(
26+
List.of(FareLegRule.of(id("r1"), FARE_PRODUCT_A).withLegGroupId(LEG_GROUP).build()),
27+
List.of(
28+
FareTransferRule.of()
29+
.withId(id("transfer"))
30+
.withFromLegGroup(LEG_GROUP)
31+
.withToLegGroup(LEG_GROUP)
32+
.withTransferCount(UNLIMITED_TRANSFERS)
33+
.withFareProducts(List.of(TRANSFER_1))
34+
.withTimeLimit(DEPARTURE_TO_DEPARTURE, Duration.ofMinutes(10))
35+
.build()
36+
),
37+
ImmutableMultimap.of()
38+
);
39+
40+
@Test
41+
void twoLegs() {
42+
var i1 = newItinerary(A, time("10:00"))
43+
.bus(1, time("10:00"), time("10:08"), B)
44+
.bus(2, time("10:09"), time("10:15"), C)
45+
.build();
46+
47+
var result = SERVICE.calculateFares(i1);
48+
49+
assertThat(result.itineraryProducts()).isEmpty();
50+
51+
var first = i1.legs().getFirst();
52+
var last = i1.legs().getLast();
53+
assertThat(result.offersForLeg(first)).containsExactly(
54+
FareOffer.of(first.startTime(), FARE_PRODUCT_A)
55+
);
56+
assertThat(result.offersForLeg(last)).containsExactly(
57+
FareOffer.of(last.startTime(), FARE_PRODUCT_A),
58+
FareOffer.of(first.startTime(), TRANSFER_1, List.of(FARE_PRODUCT_A))
59+
);
60+
}
61+
62+
@Test
63+
void twoLegsAboveLimit() {
64+
var i1 = newItinerary(A, time("10:00"))
65+
.bus(1, time("10:00"), time("10:04"), B)
66+
.bus(2, time("10:11"), time("10:15"), C)
67+
.build();
68+
69+
var result = SERVICE.calculateFares(i1);
70+
71+
assertThat(result.itineraryProducts()).isEmpty();
72+
73+
var first = i1.legs().getFirst();
74+
var last = i1.legs().getLast();
75+
assertThat(result.offersForLeg(first)).containsExactly(
76+
FareOffer.of(first.startTime(), FARE_PRODUCT_A)
77+
);
78+
assertThat(result.offersForLeg(last)).containsExactly(
79+
FareOffer.of(last.startTime(), FARE_PRODUCT_A)
80+
);
81+
}
82+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package org.opentripplanner.ext.fares.impl.gtfs;
2+
3+
import static com.google.common.truth.Truth.assertThat;
4+
import static org.opentripplanner.ext.fares.model.FareTransferRule.UNLIMITED_TRANSFERS;
5+
import static org.opentripplanner.ext.fares.model.TimeLimitType.DEPARTURE_TO_DEPARTURE;
6+
import static org.opentripplanner.model.plan.TestItineraryBuilder.newItinerary;
7+
import static org.opentripplanner.transit.model._data.TimetableRepositoryForTest.id;
8+
import static org.opentripplanner.utils.time.TimeUtils.time;
9+
10+
import com.google.common.collect.ImmutableMultimap;
11+
import java.time.Duration;
12+
import java.util.List;
13+
import org.junit.jupiter.api.Test;
14+
import org.opentripplanner.ext.fares.impl._support.FareTestConstants;
15+
import org.opentripplanner.ext.fares.model.FareLegRule;
16+
import org.opentripplanner.ext.fares.model.FareTransferRule;
17+
import org.opentripplanner.model.fare.FareOffer;
18+
import org.opentripplanner.model.plan.PlanTestConstants;
19+
import org.opentripplanner.transit.model._data.TimetableRepositoryForTest;
20+
import org.opentripplanner.transit.model.framework.FeedScopedId;
21+
import org.opentripplanner.transit.model.network.Route;
22+
23+
class FreeTransferTimeLimitTest implements PlanTestConstants, FareTestConstants {
24+
25+
private static final FeedScopedId LEG_GROUP = id("leg-group-a");
26+
private static final Route R1 = TimetableRepositoryForTest.route("r1")
27+
.withGroupOfRoutes(List.of(NETWORK_A))
28+
.build();
29+
30+
private static final GtfsFaresV2Service SERVICE = new GtfsFaresV2Service(
31+
List.of(
32+
FareLegRule.of(id("r1"), FARE_PRODUCT_A)
33+
.withLegGroupId(LEG_GROUP)
34+
.withNetworkId(NETWORK_A.getId())
35+
.build()
36+
),
37+
List.of(
38+
FareTransferRule.of()
39+
.withId(id("transfer"))
40+
.withFromLegGroup(LEG_GROUP)
41+
.withToLegGroup(LEG_GROUP)
42+
.withTransferCount(UNLIMITED_TRANSFERS)
43+
.withTimeLimit(DEPARTURE_TO_DEPARTURE, Duration.ofMinutes(10))
44+
.build()
45+
),
46+
ImmutableMultimap.of()
47+
);
48+
49+
@Test
50+
void twoLegsWithinLimit() {
51+
var i1 = newItinerary(A, time("10:00"))
52+
.bus(R1, 1, time("10:00"), time("10:03"), B)
53+
.bus(R1, 2, time("10:04"), time("10:08"), C)
54+
.bus(R1, 3, time("10:12"), time("10:22"), D)
55+
.build();
56+
57+
var result = SERVICE.calculateFares(i1);
58+
59+
assertThat(result.itineraryProducts()).isEmpty();
60+
61+
var first = i1.legs().getFirst();
62+
var second = i1.legs().get(1);
63+
var last = i1.legs().getLast();
64+
assertThat(result.offersForLeg(first)).containsExactly(
65+
FareOffer.of(first.startTime(), FARE_PRODUCT_A)
66+
);
67+
assertThat(result.offersForLeg(second)).containsExactly(
68+
FareOffer.of(first.startTime(), FARE_PRODUCT_A)
69+
);
70+
assertThat(result.offersForLeg(last)).containsExactly(
71+
FareOffer.of(second.startTime(), FARE_PRODUCT_A)
72+
);
73+
}
74+
}

0 commit comments

Comments
 (0)