stopTimesForTrip, TransferDirection transferDirection) {
+ switch (transferDirection) {
+ case TRANSFER_FROM:
+ return stopTimesForTrip.get(stopTimesForTrip.size() - 1);
+ case TRANSFER_TO:
+ return stopTimesForTrip.get(0);
+ default:
+ throw new UnsupportedOperationException("Unhandled TransferDirection=" + transferDirection);
+ }
+ }
+
+ /**
+ * A `from_trip_id` or `to_trip_id` field from GTFS file `transfers.txt` with an in-seat transfer
+ * type references a stop that is not in the expected position in the trip's stop-times.
+ *
+ * For in-seat transfers, we expect the stop to be the last stop-time in the trip sequence for
+ * `from_stop_id` and the first stop-time for `to_stop_id`. If you are intentionally using this
+ * feature to model mid-trip transfers, you can ignore this warning, but be aware that this
+ * functionality is still considered to be partially experimental in some interpretations of the
+ * spec.
+ *
+ *
Severity: {@code SeverityLevel.WARNING}
+ */
+ public static class TransferWithSuspiciousMidTripInSeatNotice extends ValidationNotice {
+ // The row number from `transfers.txt` for the faulty entry.
+ private final long csvRowNumber;
+ // The name of the trip id field (e.g. `from_trip_id`) referencing a trip.
+ private final String tripIdFieldName;
+ // The referenced trip id.
+ private final String tripId;
+ // The name of the stop id field (e.g. `from_stop_id`) referencing the stop.
+ private final String stopIdFieldName;
+ // The referenced stop id.
+ private final String stopId;
+
+ public TransferWithSuspiciousMidTripInSeatNotice(
+ GtfsTransfer transfer, TransferDirection transferDirection) {
+ super(SeverityLevel.WARNING);
+ this.csvRowNumber = transfer.csvRowNumber();
+ this.tripIdFieldName = transferDirection.tripIdFieldName();
+ this.tripId = transferDirection.tripId(transfer);
+ this.stopIdFieldName = transferDirection.stopIdFieldName();
+ this.stopId = transferDirection.stopId(transfer);
+ }
+ }
+}
diff --git a/main/src/main/java/org/mobilitydata/gtfsvalidator/validator/TransfersStopTypeValidator.java b/main/src/main/java/org/mobilitydata/gtfsvalidator/validator/TransfersStopTypeValidator.java
index c4a38c7399..891a7a6a86 100644
--- a/main/src/main/java/org/mobilitydata/gtfsvalidator/validator/TransfersStopTypeValidator.java
+++ b/main/src/main/java/org/mobilitydata/gtfsvalidator/validator/TransfersStopTypeValidator.java
@@ -11,7 +11,6 @@
import org.mobilitydata.gtfsvalidator.table.GtfsStopTableContainer;
import org.mobilitydata.gtfsvalidator.table.GtfsTransfer;
import org.mobilitydata.gtfsvalidator.table.GtfsTransferTableContainer;
-import org.mobilitydata.gtfsvalidator.table.GtfsTransferTableLoader;
/**
* Validates that {@code transfers.from_stop_id} and {@code to_stop_id} reference stops or stations.
@@ -36,18 +35,13 @@ public void validate(NoticeContainer noticeContainer) {
}
public void validateEntity(GtfsTransfer entity, NoticeContainer noticeContainer) {
- validateStopType(
- entity,
- GtfsTransferTableLoader.FROM_STOP_ID_FIELD_NAME,
- entity.fromStopId(),
- noticeContainer);
- validateStopType(
- entity, GtfsTransferTableLoader.TO_STOP_ID_FIELD_NAME, entity.toStopId(), noticeContainer);
+ validateStopType(entity, TransferDirection.TRANSFER_FROM, noticeContainer);
+ validateStopType(entity, TransferDirection.TRANSFER_TO, noticeContainer);
}
private void validateStopType(
- GtfsTransfer entity, String stopIdFieldName, String stopId, NoticeContainer noticeContainer) {
- Optional optStop = stopsContainer.byStopId(stopId);
+ GtfsTransfer entity, TransferDirection transferDirection, NoticeContainer noticeContainer) {
+ Optional optStop = stopsContainer.byStopId(transferDirection.stopId(entity));
if (optStop.isEmpty()) {
// Foreign key reference is validated elsewhere.
return;
@@ -56,8 +50,7 @@ private void validateStopType(
GtfsLocationType locationType = optStop.get().locationType();
if (!isValidTransferStopType(locationType)) {
noticeContainer.addValidationNotice(
- new TransferWithInvalidStopLocationTypeNotice(
- entity.csvRowNumber(), stopIdFieldName, stopId, locationType));
+ new TransferWithInvalidStopLocationTypeNotice(entity, transferDirection, locationType));
}
}
@@ -90,11 +83,11 @@ public static final class TransferWithInvalidStopLocationTypeNotice extends Vali
private String locationTypeName;
public TransferWithInvalidStopLocationTypeNotice(
- long csvRowNumber, String stopIdFieldName, String stopId, GtfsLocationType locationType) {
+ GtfsTransfer transfer, TransferDirection transferDirection, GtfsLocationType locationType) {
super(SeverityLevel.ERROR);
- this.csvRowNumber = csvRowNumber;
- this.stopIdFieldName = stopIdFieldName;
- this.stopId = stopId;
+ this.csvRowNumber = transfer.csvRowNumber();
+ this.stopIdFieldName = transferDirection.stopIdFieldName();
+ this.stopId = transferDirection.stopId(transfer);
this.locationTypeValue = locationType.getNumber();
this.locationTypeName = locationType.toString();
}
diff --git a/main/src/main/java/org/mobilitydata/gtfsvalidator/validator/TransfersTripReferenceValidator.java b/main/src/main/java/org/mobilitydata/gtfsvalidator/validator/TransfersTripReferenceValidator.java
index a2ff52df55..67bd87914f 100644
--- a/main/src/main/java/org/mobilitydata/gtfsvalidator/validator/TransfersTripReferenceValidator.java
+++ b/main/src/main/java/org/mobilitydata/gtfsvalidator/validator/TransfersTripReferenceValidator.java
@@ -1,5 +1,7 @@
package org.mobilitydata.gtfsvalidator.validator;
+import static org.mobilitydata.gtfsvalidator.validator.ValidatorReference.validatedElsewhereBy;
+
import com.google.common.collect.ImmutableSet;
import java.util.List;
import java.util.Optional;
@@ -15,7 +17,6 @@
import org.mobilitydata.gtfsvalidator.table.GtfsStopTimeTableContainer;
import org.mobilitydata.gtfsvalidator.table.GtfsTransfer;
import org.mobilitydata.gtfsvalidator.table.GtfsTransferTableContainer;
-import org.mobilitydata.gtfsvalidator.table.GtfsTransferTableLoader;
import org.mobilitydata.gtfsvalidator.table.GtfsTrip;
import org.mobilitydata.gtfsvalidator.table.GtfsTripTableContainer;
@@ -51,90 +52,57 @@ public void validate(NoticeContainer noticeContainer) {
}
public void validateEntity(GtfsTransfer entity, NoticeContainer noticeContainer) {
- validateTripReferences(
- entity,
- GtfsTransferTableLoader.FROM_TRIP_ID_FIELD_NAME,
- optional(entity.hasFromTripId(), entity.fromTripId()),
- GtfsTransferTableLoader.FROM_ROUTE_ID_FIELD_NAME,
- optional(entity.hasFromRouteId(), entity.fromRouteId()),
- GtfsTransferTableLoader.FROM_STOP_ID_FIELD_NAME,
- optional(entity.hasFromStopId(), entity.fromStopId()),
- noticeContainer);
- validateTripReferences(
- entity,
- GtfsTransferTableLoader.TO_TRIP_ID_FIELD_NAME,
- optional(entity.hasToTripId(), entity.toTripId()),
- GtfsTransferTableLoader.TO_ROUTE_ID_FIELD_NAME,
- optional(entity.hasToRouteId(), entity.toRouteId()),
- GtfsTransferTableLoader.TO_STOP_ID_FIELD_NAME,
- optional(entity.hasToStopId(), entity.toStopId()),
- noticeContainer);
+ for (TransferDirection transferDirection : TransferDirection.values()) {
+ validateTripReferences(entity, transferDirection, noticeContainer);
+ }
}
void validateTripReferences(
- GtfsTransfer entity,
- String tripFieldName,
- Optional tripId,
- String routeFieldName,
- Optional routeId,
- String stopFieldName,
- Optional stopId,
- NoticeContainer noticeContainer) {
- if (tripId.isEmpty()) {
+ GtfsTransfer entity, TransferDirection transferDirection, NoticeContainer noticeContainer) {
+ if (!transferDirection.hasTripId(entity)) {
return;
}
- Optional optTrip = tripsContainer.byTripId(tripId.get());
+ Optional optTrip = tripsContainer.byTripId(transferDirection.tripId(entity));
if (optTrip.isEmpty()) {
- // The foreign key reference is validated elsewhere.
+ // The foreign key reference is
+ validatedElsewhereBy(
+ GtfsTransferFromTripIdForeignKeyValidator.class,
+ GtfsTransferToTripIdForeignKeyValidator.class);
return;
}
GtfsTrip trip = optTrip.get();
- if (routeId.isPresent()) {
- if (!trip.routeId().equals(routeId.get())) {
+ if (transferDirection.hasRouteId(entity)) {
+ if (!trip.routeId().equals(transferDirection.routeId(entity))) {
noticeContainer.addValidationNotice(
- new TransferWithInvalidTripAndRouteNotice(
- entity.csvRowNumber(),
- tripFieldName,
- tripId.get(),
- routeFieldName,
- routeId.get(),
- trip.routeId()));
+ new TransferWithInvalidTripAndRouteNotice(entity, transferDirection, trip.routeId()));
}
}
- if (stopId.isPresent()) {
- validateTripStopReference(
- entity, tripFieldName, tripId, stopFieldName, stopId.get(), noticeContainer);
+ if (transferDirection.hasStopId(entity)) {
+ validateTripStopReference(entity, transferDirection, noticeContainer);
}
}
private void validateTripStopReference(
- GtfsTransfer entity,
- String tripFieldName,
- Optional tripId,
- String stopFieldName,
- String stopId,
- NoticeContainer noticeContainer) {
- Optional optStop = stopsContainer.byStopId(stopId);
+ GtfsTransfer entity, TransferDirection transferDirection, NoticeContainer noticeContainer) {
+ Optional optStop = stopsContainer.byStopId(transferDirection.stopId(entity));
if (optStop.isEmpty()) {
- // The foreign key reference is validated elsewhere.
+ // The foreign key reference is
+ validatedElsewhereBy(
+ GtfsTransferFromStopIdForeignKeyValidator.class,
+ GtfsTransferToStopIdForeignKeyValidator.class);
return;
}
ImmutableSet stops = expandStationIfNeeded(optStop.get());
ImmutableSet ids =
stops.stream().map(GtfsStop::stopId).collect(ImmutableSet.toImmutableSet());
- List stopTimes = stopTimeContainer.byTripId(tripId.get());
+ List stopTimes = stopTimeContainer.byTripId(transferDirection.tripId(entity));
if (!stopTimes.stream().anyMatch((st) -> ids.contains(st.stopId()))) {
noticeContainer.addValidationNotice(
- new TransferWithInvalidTripAndStopNotice(
- entity.csvRowNumber(), tripFieldName, tripId.get(), stopFieldName, stopId));
+ new TransferWithInvalidTripAndStopNotice(entity, transferDirection));
}
}
- private static Optional optional(boolean hasValue, T value) {
- return hasValue ? Optional.of(value) : Optional.empty();
- }
-
private ImmutableSet expandStationIfNeeded(GtfsStop stop) {
if (stop.locationType() == GtfsLocationType.STOP) {
return ImmutableSet.of(stop);
@@ -168,18 +136,13 @@ public static class TransferWithInvalidTripAndRouteNotice extends ValidationNoti
private final String expectedRouteId;
public TransferWithInvalidTripAndRouteNotice(
- long csvRowNumber,
- String tripFieldName,
- String tripId,
- String routeFieldName,
- String routeId,
- String expectedRouteId) {
+ GtfsTransfer transfer, TransferDirection transferDirection, String expectedRouteId) {
super(SeverityLevel.ERROR);
- this.csvRowNumber = csvRowNumber;
- this.tripFieldName = tripFieldName;
- this.tripId = tripId;
- this.routeFieldName = routeFieldName;
- this.routeId = routeId;
+ this.csvRowNumber = transfer.csvRowNumber();
+ this.tripFieldName = transferDirection.tripIdFieldName();
+ this.tripId = transferDirection.tripId(transfer);
+ this.routeFieldName = transferDirection.routeIdFieldName();
+ this.routeId = transferDirection.routeId(transfer);
this.expectedRouteId = expectedRouteId;
}
}
@@ -203,17 +166,13 @@ public static class TransferWithInvalidTripAndStopNotice extends ValidationNotic
private final String stopId;
public TransferWithInvalidTripAndStopNotice(
- long csvRowNumber,
- String tripFieldName,
- String tripId,
- String stopFieldName,
- String stopId) {
+ GtfsTransfer transfer, TransferDirection transferDirection) {
super(SeverityLevel.ERROR);
- this.csvRowNumber = csvRowNumber;
- this.tripFieldName = tripFieldName;
- this.tripId = tripId;
- this.stopFieldName = stopFieldName;
- this.stopId = stopId;
+ this.csvRowNumber = transfer.csvRowNumber();
+ this.tripFieldName = transferDirection.tripIdFieldName();
+ this.tripId = transferDirection.tripId(transfer);
+ this.stopFieldName = transferDirection.stopIdFieldName();
+ this.stopId = transferDirection.stopId(transfer);
}
}
}
diff --git a/main/src/test/java/org/mobilitydata/gtfsvalidator/validator/TransferDirectionTest.java b/main/src/test/java/org/mobilitydata/gtfsvalidator/validator/TransferDirectionTest.java
new file mode 100644
index 0000000000..6f965a11fe
--- /dev/null
+++ b/main/src/test/java/org/mobilitydata/gtfsvalidator/validator/TransferDirectionTest.java
@@ -0,0 +1,76 @@
+package org.mobilitydata.gtfsvalidator.validator;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mobilitydata.gtfsvalidator.validator.TransferDirection.TRANSFER_FROM;
+import static org.mobilitydata.gtfsvalidator.validator.TransferDirection.TRANSFER_TO;
+
+import org.junit.Test;
+import org.mobilitydata.gtfsvalidator.table.GtfsTransfer;
+import org.mobilitydata.gtfsvalidator.table.GtfsTransfer.Builder;
+
+public class TransferDirectionTest {
+
+ @Test
+ public void testFieldName() {
+ assertThat(TRANSFER_FROM.stopIdFieldName()).isEqualTo("from_stop_id");
+ assertThat(TRANSFER_TO.stopIdFieldName()).isEqualTo("to_stop_id");
+
+ assertThat(TRANSFER_FROM.routeIdFieldName()).isEqualTo("from_route_id");
+ assertThat(TRANSFER_TO.routeIdFieldName()).isEqualTo("to_route_id");
+
+ assertThat(TRANSFER_FROM.tripIdFieldName()).isEqualTo("from_trip_id");
+ assertThat(TRANSFER_TO.tripIdFieldName()).isEqualTo("to_trip_id");
+ }
+
+ @Test
+ public void testHasMethodsForEmptyTransfer() {
+ GtfsTransfer emptyTransfer = new Builder().build();
+
+ assertThat(TRANSFER_FROM.hasStopId(emptyTransfer)).isFalse();
+ assertThat(TRANSFER_TO.hasStopId(emptyTransfer)).isFalse();
+
+ assertThat(TRANSFER_FROM.hasRouteId(emptyTransfer)).isFalse();
+ assertThat(TRANSFER_TO.hasRouteId(emptyTransfer)).isFalse();
+
+ assertThat(TRANSFER_FROM.hasTripId(emptyTransfer)).isFalse();
+ assertThat(TRANSFER_TO.hasTripId(emptyTransfer)).isFalse();
+ }
+
+ @Test
+ public void testHasMethods() {
+ assertThat(TRANSFER_FROM.hasStopId(new GtfsTransfer.Builder().setFromStopId("a").build()))
+ .isTrue();
+ assertThat(TRANSFER_TO.hasStopId(new GtfsTransfer.Builder().setToStopId("a").build())).isTrue();
+
+ assertThat(TRANSFER_FROM.hasRouteId(new GtfsTransfer.Builder().setFromRouteId("a").build()))
+ .isTrue();
+ assertThat(TRANSFER_TO.hasRouteId(new GtfsTransfer.Builder().setToRouteId("a").build()))
+ .isTrue();
+
+ assertThat(TRANSFER_FROM.hasTripId(new GtfsTransfer.Builder().setFromTripId("a").build()))
+ .isTrue();
+ assertThat(TRANSFER_TO.hasTripId(new GtfsTransfer.Builder().setToTripId("a").build())).isTrue();
+ }
+
+ @Test
+ public void testIdMethods() {
+ GtfsTransfer transfer =
+ new Builder()
+ .setFromStopId("stopA")
+ .setFromRouteId("routeA")
+ .setFromTripId("tripA")
+ .setToStopId("stopB")
+ .setToRouteId("routeB")
+ .setToTripId("tripB")
+ .build();
+
+ assertThat(TRANSFER_FROM.stopId(transfer)).isEqualTo("stopA");
+ assertThat(TRANSFER_TO.stopId(transfer)).isEqualTo("stopB");
+
+ assertThat(TRANSFER_FROM.routeId(transfer)).isEqualTo("routeA");
+ assertThat(TRANSFER_TO.routeId(transfer)).isEqualTo("routeB");
+
+ assertThat(TRANSFER_FROM.tripId(transfer)).isEqualTo("tripA");
+ assertThat(TRANSFER_TO.tripId(transfer)).isEqualTo("tripB");
+ }
+}
diff --git a/main/src/test/java/org/mobilitydata/gtfsvalidator/validator/TransfersInSeatTransferTypeValidatorTest.java b/main/src/test/java/org/mobilitydata/gtfsvalidator/validator/TransfersInSeatTransferTypeValidatorTest.java
new file mode 100644
index 0000000000..fd0611ae1e
--- /dev/null
+++ b/main/src/test/java/org/mobilitydata/gtfsvalidator/validator/TransfersInSeatTransferTypeValidatorTest.java
@@ -0,0 +1,199 @@
+package org.mobilitydata.gtfsvalidator.validator;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.ImmutableList;
+import org.junit.Test;
+import org.mobilitydata.gtfsvalidator.notice.NoticeContainer;
+import org.mobilitydata.gtfsvalidator.table.GtfsLocationType;
+import org.mobilitydata.gtfsvalidator.table.GtfsStop;
+import org.mobilitydata.gtfsvalidator.table.GtfsStopTableContainer;
+import org.mobilitydata.gtfsvalidator.table.GtfsStopTime;
+import org.mobilitydata.gtfsvalidator.table.GtfsStopTimeTableContainer;
+import org.mobilitydata.gtfsvalidator.table.GtfsTransfer;
+import org.mobilitydata.gtfsvalidator.table.GtfsTransfer.Builder;
+import org.mobilitydata.gtfsvalidator.table.GtfsTransferTableContainer;
+import org.mobilitydata.gtfsvalidator.table.GtfsTransferType;
+import org.mobilitydata.gtfsvalidator.validator.TransfersInSeatTransferTypeValidator.TransferWithSuspiciousMidTripInSeatNotice;
+import org.mobilitydata.gtfsvalidator.validator.TransfersStopTypeValidator.TransferWithInvalidStopLocationTypeNotice;
+
+public class TransfersInSeatTransferTypeValidatorTest {
+
+ private final NoticeContainer noticeContainer = new NoticeContainer();
+
+ @Test
+ public void testValidInSeatTransfer() {
+ // In-seat transfer between the last stop of the from-trip and the first-stop of the to-trip.
+ GtfsStopTableContainer stops =
+ GtfsStopTableContainer.forEntities(
+ ImmutableList.of(
+ new GtfsStop.Builder()
+ .setStopId("s0")
+ .setLocationType(GtfsLocationType.STOP)
+ .build(),
+ new GtfsStop.Builder()
+ .setStopId("s1")
+ .setLocationType(GtfsLocationType.STOP)
+ .build()),
+ noticeContainer);
+ GtfsStopTimeTableContainer stopTimes =
+ GtfsStopTimeTableContainer.forEntities(
+ ImmutableList.of(
+ new GtfsStopTime.Builder()
+ .setTripId("t0")
+ .setStopId("s?")
+ .setStopSequence(0)
+ .build(),
+ new GtfsStopTime.Builder()
+ .setTripId("t0")
+ .setStopId("s0")
+ .setStopSequence(1)
+ .build(),
+ new GtfsStopTime.Builder()
+ .setTripId("t1")
+ .setStopId("s1")
+ .setStopSequence(0)
+ .build(),
+ new GtfsStopTime.Builder()
+ .setTripId("t1")
+ .setStopId("s?")
+ .setStopSequence(1)
+ .build()),
+ noticeContainer);
+ GtfsTransferTableContainer transfers =
+ GtfsTransferTableContainer.forEntities(
+ ImmutableList.of(
+ new GtfsTransfer.Builder()
+ .setCsvRowNumber(2)
+ .setFromStopId("s0")
+ .setToStopId("s1")
+ .setFromTripId("t0")
+ .setToTripId("t1")
+ .setTransferType(GtfsTransferType.IN_SEAT_TRANSFER_ALLOWED)
+ .build()),
+ noticeContainer);
+
+ new TransfersInSeatTransferTypeValidator(transfers, stops, stopTimes).validate(noticeContainer);
+
+ assertThat(noticeContainer.getValidationNotices()).isEmpty();
+ }
+
+ @Test
+ public void testInvalidInSeatTransferToStation() {
+ // Invalid: `to_stop_id` refers to a station, which is forbidden for in-seat transfers.
+ GtfsStopTableContainer stops =
+ GtfsStopTableContainer.forEntities(
+ ImmutableList.of(
+ new GtfsStop.Builder()
+ .setStopId("s0")
+ .setLocationType(GtfsLocationType.STOP)
+ .build(),
+ new GtfsStop.Builder()
+ .setStopId("s1")
+ .setLocationType(GtfsLocationType.STATION)
+ .build()),
+ noticeContainer);
+ GtfsStopTimeTableContainer stopTimes =
+ GtfsStopTimeTableContainer.forEntities(
+ ImmutableList.of(
+ new GtfsStopTime.Builder()
+ .setTripId("t0")
+ .setStopId("s?")
+ .setStopSequence(0)
+ .build(),
+ new GtfsStopTime.Builder()
+ .setTripId("t0")
+ .setStopId("s0")
+ .setStopSequence(1)
+ .build(),
+ new GtfsStopTime.Builder()
+ .setTripId("t1")
+ .setStopId("s1")
+ .setStopSequence(0)
+ .build(),
+ new GtfsStopTime.Builder()
+ .setTripId("t1")
+ .setStopId("s?")
+ .setStopSequence(1)
+ .build()),
+ noticeContainer);
+ GtfsTransfer transfer =
+ new Builder()
+ .setCsvRowNumber(2)
+ .setFromStopId("s0")
+ .setToStopId("s1")
+ .setFromTripId("t0")
+ .setToTripId("t1")
+ .setTransferType(GtfsTransferType.IN_SEAT_TRANSFER_ALLOWED)
+ .build();
+ GtfsTransferTableContainer transfers =
+ GtfsTransferTableContainer.forEntities(ImmutableList.of(transfer), noticeContainer);
+
+ new TransfersInSeatTransferTypeValidator(transfers, stops, stopTimes).validate(noticeContainer);
+
+ assertThat(noticeContainer.getValidationNotices())
+ .containsExactly(
+ new TransferWithInvalidStopLocationTypeNotice(
+ transfer, TransferDirection.TRANSFER_TO, GtfsLocationType.STATION));
+ }
+
+ @Test
+ public void testSuspiciousMidTripInSeatTransfer() {
+ // Invalid: `to_stop_id` refers to a station, which is forbidden for in-seat transfers.
+ GtfsStopTableContainer stops =
+ GtfsStopTableContainer.forEntities(
+ ImmutableList.of(
+ new GtfsStop.Builder()
+ .setStopId("s0")
+ .setLocationType(GtfsLocationType.STOP)
+ .build(),
+ new GtfsStop.Builder()
+ .setStopId("s1")
+ .setLocationType(GtfsLocationType.STOP)
+ .build()),
+ noticeContainer);
+ GtfsStopTimeTableContainer stopTimes =
+ GtfsStopTimeTableContainer.forEntities(
+ ImmutableList.of(
+ new GtfsStopTime.Builder()
+ .setTripId("t0")
+ .setStopId("s0")
+ .setStopSequence(0)
+ .build(),
+ new GtfsStopTime.Builder()
+ .setTripId("t0")
+ .setStopId("s?")
+ .setStopSequence(1)
+ .build(),
+ new GtfsStopTime.Builder()
+ .setTripId("t1")
+ .setStopId("s?")
+ .setStopSequence(0)
+ .build(),
+ new GtfsStopTime.Builder()
+ .setTripId("t1")
+ .setStopId("s1")
+ .setStopSequence(1)
+ .build()),
+ noticeContainer);
+ GtfsTransfer transfer =
+ new Builder()
+ .setCsvRowNumber(2)
+ .setFromStopId("s0")
+ .setToStopId("s1")
+ .setFromTripId("t0")
+ .setToTripId("t1")
+ .setTransferType(GtfsTransferType.IN_SEAT_TRANSFER_ALLOWED)
+ .build();
+ GtfsTransferTableContainer transfers =
+ GtfsTransferTableContainer.forEntities(ImmutableList.of(transfer), noticeContainer);
+
+ new TransfersInSeatTransferTypeValidator(transfers, stops, stopTimes).validate(noticeContainer);
+
+ assertThat(noticeContainer.getValidationNotices())
+ .containsExactly(
+ new TransferWithSuspiciousMidTripInSeatNotice(
+ transfer, TransferDirection.TRANSFER_FROM),
+ new TransferWithSuspiciousMidTripInSeatNotice(transfer, TransferDirection.TRANSFER_TO));
+ }
+}
diff --git a/main/src/test/java/org/mobilitydata/gtfsvalidator/validator/TransfersStopTypeValidatorTest.java b/main/src/test/java/org/mobilitydata/gtfsvalidator/validator/TransfersStopTypeValidatorTest.java
index 06dccbfd8b..0add19d140 100644
--- a/main/src/test/java/org/mobilitydata/gtfsvalidator/validator/TransfersStopTypeValidatorTest.java
+++ b/main/src/test/java/org/mobilitydata/gtfsvalidator/validator/TransfersStopTypeValidatorTest.java
@@ -15,7 +15,7 @@
public class TransfersStopTypeValidatorTest {
- private NoticeContainer noticeContainer = new NoticeContainer();
+ private final NoticeContainer noticeContainer = new NoticeContainer();
@Test
public void testStopToStationTransfer() {
@@ -53,24 +53,23 @@ public void testEntranceToGenericNodeTransfer() {
.setLocationType(GtfsLocationType.GENERIC_NODE)
.build()),
noticeContainer);
+ GtfsTransfer transfer =
+ new GtfsTransfer.Builder()
+ .setCsvRowNumber(2)
+ .setFromStopId("s0")
+ .setToStopId("s1")
+ .setTransferType(GtfsTransferType.RECOMMENDED)
+ .build();
GtfsTransferTableContainer transfers =
- GtfsTransferTableContainer.forEntities(
- ImmutableList.of(
- new GtfsTransfer.Builder()
- .setCsvRowNumber(2)
- .setFromStopId("s0")
- .setToStopId("s1")
- .setTransferType(GtfsTransferType.RECOMMENDED)
- .build()),
- noticeContainer);
+ GtfsTransferTableContainer.forEntities(ImmutableList.of(transfer), noticeContainer);
new TransfersStopTypeValidator(transfers, stops).validate(noticeContainer);
assertThat(noticeContainer.getValidationNotices())
.containsExactly(
new TransferWithInvalidStopLocationTypeNotice(
- 2, "from_stop_id", "s0", GtfsLocationType.ENTRANCE),
+ transfer, TransferDirection.TRANSFER_FROM, GtfsLocationType.ENTRANCE),
new TransferWithInvalidStopLocationTypeNotice(
- 2, "to_stop_id", "s1", GtfsLocationType.GENERIC_NODE));
+ transfer, TransferDirection.TRANSFER_TO, GtfsLocationType.GENERIC_NODE));
}
}
diff --git a/main/src/test/java/org/mobilitydata/gtfsvalidator/validator/TransfersTripReferenceValidatorTest.java b/main/src/test/java/org/mobilitydata/gtfsvalidator/validator/TransfersTripReferenceValidatorTest.java
index f541be2e17..ecb7bf97f6 100644
--- a/main/src/test/java/org/mobilitydata/gtfsvalidator/validator/TransfersTripReferenceValidatorTest.java
+++ b/main/src/test/java/org/mobilitydata/gtfsvalidator/validator/TransfersTripReferenceValidatorTest.java
@@ -20,7 +20,7 @@
public class TransfersTripReferenceValidatorTest {
- private NoticeContainer noticeContainer = new NoticeContainer();
+ private final NoticeContainer noticeContainer = new NoticeContainer();
@Test
public void testValidTripReferences() {
@@ -93,22 +93,21 @@ public void testInvalidTripReferences() {
new GtfsStopTime.Builder().setTripId("t0").setStopId("s0").build(),
new GtfsStopTime.Builder().setTripId("t1").setStopId("s1").build()),
noticeContainer);
+ GtfsTransfer transfer =
+ new GtfsTransfer.Builder()
+ .setCsvRowNumber(2)
+ .setFromStopId("s0")
+ // This is not the expected route id.
+ .setFromRouteId("DNE")
+ .setFromTripId("t0")
+ // This stop is not associated with the trip's stop-times.
+ .setToStopId("s2")
+ .setToRouteId("r1")
+ .setToTripId("t1")
+ .setTransferType(GtfsTransferType.IMPOSSIBLE)
+ .build();
GtfsTransferTableContainer transfers =
- GtfsTransferTableContainer.forEntities(
- ImmutableList.of(
- new GtfsTransfer.Builder()
- .setCsvRowNumber(2)
- .setFromStopId("s0")
- // This is not the expected route id.
- .setFromRouteId("DNE")
- .setFromTripId("t0")
- // This stop is not associated with the trip's stop-times.
- .setToStopId("s2")
- .setToRouteId("r1")
- .setToTripId("t1")
- .setTransferType(GtfsTransferType.IMPOSSIBLE)
- .build()),
- noticeContainer);
+ GtfsTransferTableContainer.forEntities(ImmutableList.of(transfer), noticeContainer);
new TransfersTripReferenceValidator(transfers, trips, stopTimes, stops)
.validate(noticeContainer);
@@ -116,7 +115,7 @@ public void testInvalidTripReferences() {
assertThat(noticeContainer.getValidationNotices())
.containsExactly(
new TransferWithInvalidTripAndRouteNotice(
- 2, "from_trip_id", "t0", "from_route_id", "DNE", "r0"),
- new TransferWithInvalidTripAndStopNotice(2, "to_trip_id", "t1", "to_stop_id", "s2"));
+ transfer, TransferDirection.TRANSFER_FROM, "r0"),
+ new TransferWithInvalidTripAndStopNotice(transfer, TransferDirection.TRANSFER_TO));
}
}