diff --git a/src/main/java/com/conveyal/gtfs/error/NewGTFSErrorType.java b/src/main/java/com/conveyal/gtfs/error/NewGTFSErrorType.java index 49f44fa3f..477c034dc 100644 --- a/src/main/java/com/conveyal/gtfs/error/NewGTFSErrorType.java +++ b/src/main/java/com/conveyal/gtfs/error/NewGTFSErrorType.java @@ -47,6 +47,7 @@ public enum NewGTFSErrorType { ROUTE_LONG_NAME_CONTAINS_SHORT_NAME(Priority.LOW, "The long name of a route should complement the short name, not include it."), ROUTE_SHORT_AND_LONG_NAME_MISSING(Priority.MEDIUM, "A route has neither a long nor a short name."), ROUTE_SHORT_NAME_TOO_LONG(Priority.MEDIUM, "The short name of a route is too long for display in standard GTFS consumer applications."), + ROUTE_TYPE_INVALID(Priority.MEDIUM, "The route type is not valid."), ROUTE_UNUSED(Priority.MEDIUM, "This route is defined but has no trips."), SERVICE_NEVER_ACTIVE(Priority.MEDIUM, "A service code was defined, but is never active on any date."), SERVICE_UNUSED(Priority.MEDIUM, "A service code was defined, but is never referenced by any trips."), diff --git a/src/main/java/com/conveyal/gtfs/validator/RouteTypeValidator.java b/src/main/java/com/conveyal/gtfs/validator/RouteTypeValidator.java new file mode 100644 index 000000000..740694297 --- /dev/null +++ b/src/main/java/com/conveyal/gtfs/validator/RouteTypeValidator.java @@ -0,0 +1,56 @@ +package com.conveyal.gtfs.validator; + +import com.conveyal.gtfs.error.SQLErrorStorage; +import com.conveyal.gtfs.loader.Feed; +import com.conveyal.gtfs.model.Route; + +import java.util.List; + +import static com.conveyal.gtfs.error.NewGTFSErrorType.ROUTE_TYPE_INVALID; + +/** + * Validates route types based on a configured list of values. + */ +public class RouteTypeValidator extends FeedValidator { + private final List configuredRouteTypes; + + /** + * Constructor used for tests in the same package. + */ + RouteTypeValidator(List routeTypes) { + this(null, null, routeTypes); + } + + /** + * Constructor for building a route type validator given a set of valid route types. + */ + public RouteTypeValidator(Feed feed, SQLErrorStorage errorStorage, List routeTypes) { + super(feed, errorStorage); + this.configuredRouteTypes = routeTypes; + } + + @Override + public void validate() { + feed.routes.forEach(this::validateRouteType); + } + + /** + * @return true if routeType is one of the configured route types, false otherwise. + */ + public boolean isRouteTypeValid(int routeType) { + return configuredRouteTypes.contains(routeType); + } + + /** + * Checks that the route type is valid, reports a validation error if not. + * @param route The containing GTFS route. + * @return true if the route type for the given route is valid, false otherwise. + */ + public boolean validateRouteType(Route route) { + if (!isRouteTypeValid(route.route_type)) { + if (errorStorage != null) registerError(route, ROUTE_TYPE_INVALID, route.route_type); + return false; + } + return true; + } +} diff --git a/src/test/java/com/conveyal/gtfs/validator/RouteTypeValidatorTest.java b/src/test/java/com/conveyal/gtfs/validator/RouteTypeValidatorTest.java new file mode 100644 index 000000000..4303f3dc6 --- /dev/null +++ b/src/test/java/com/conveyal/gtfs/validator/RouteTypeValidatorTest.java @@ -0,0 +1,21 @@ +package com.conveyal.gtfs.validator; + +import com.google.common.collect.Lists; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class RouteTypeValidatorTest { + private static final List TEST_ROUTE_TYPES = Lists.newArrayList(3, 101); + private static final RouteTypeValidator ROUTE_TYPE_VALIDATOR = new RouteTypeValidator(TEST_ROUTE_TYPES); + + @Test + void validateRouteType() { + assertTrue(ROUTE_TYPE_VALIDATOR.isRouteTypeValid(3)); // Bus + assertFalse(ROUTE_TYPE_VALIDATOR.isRouteTypeValid(36)); // Invalid + assertTrue(ROUTE_TYPE_VALIDATOR.isRouteTypeValid(101)); // High Speed Rail + } +}