Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.mobilitydata.gtfsvalidator.validator;

import org.mobilitydata.gtfsvalidator.annotation.GtfsValidator;
import org.mobilitydata.gtfsvalidator.notice.MissingRecommendedFieldNotice;
import org.mobilitydata.gtfsvalidator.notice.NoticeContainer;
import org.mobilitydata.gtfsvalidator.table.GtfsPathway;
import org.mobilitydata.gtfsvalidator.table.GtfsPathwayMode;

/**
* Validates that {@code stair_count} is provided for pathways that are stairs.
*
* <p>The GTFS specification recommends {@code pathways.stair_count} for stairs ({@code
* pathway_mode=2}). Without it, a consumer cannot tell how many steps a path involves, which is
* information riders with limited mobility rely on when choosing a route through a station.
*
* <p>Generated notice: {@link MissingRecommendedFieldNotice}.
*/
@GtfsValidator
public class PathwayStairCountValidator extends SingleEntityValidator<GtfsPathway> {

@Override
public void validate(GtfsPathway entity, NoticeContainer noticeContainer) {
if (entity.pathwayMode() == GtfsPathwayMode.STAIRS && !entity.hasStairCount()) {
noticeContainer.addValidationNotice(
new MissingRecommendedFieldNotice(
GtfsPathway.FILENAME, entity.csvRowNumber(), GtfsPathway.STAIR_COUNT_FIELD_NAME));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.mobilitydata.gtfsvalidator.validator;

import static com.google.common.truth.Truth.assertThat;

import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mobilitydata.gtfsvalidator.notice.MissingRecommendedFieldNotice;
import org.mobilitydata.gtfsvalidator.notice.NoticeContainer;
import org.mobilitydata.gtfsvalidator.notice.ValidationNotice;
import org.mobilitydata.gtfsvalidator.table.GtfsPathway;
import org.mobilitydata.gtfsvalidator.table.GtfsPathwayMode;

@RunWith(JUnit4.class)
public class PathwayStairCountValidatorTest {

@Test
public void stairsWithoutStairCount_yieldsNotice() {
assertThat(validationNoticesFor(pathwayBuilder(GtfsPathwayMode.STAIRS).build()))
.containsExactly(new MissingRecommendedFieldNotice("pathways.txt", 2, "stair_count"));
}

@Test
public void stairsWithStairCount_yieldsNoNotice() {
assertThat(
validationNoticesFor(pathwayBuilder(GtfsPathwayMode.STAIRS).setStairCount(5).build()))
.isEmpty();
}

@Test
public void stairsWithNegativeStairCount_yieldsNoNotice() {
// stair_count is signed: a negative value describes a descending path, so it is still defined.
assertThat(
validationNoticesFor(pathwayBuilder(GtfsPathwayMode.STAIRS).setStairCount(-5).build()))
.isEmpty();
}

@Test
public void nonStairsWithoutStairCount_yieldsNoNotice() {
for (GtfsPathwayMode mode : GtfsPathwayMode.values()) {
if (mode == GtfsPathwayMode.STAIRS) {
continue;
}
assertThat(validationNoticesFor(pathwayBuilder(mode).build())).isEmpty();
}
}

private static GtfsPathway.Builder pathwayBuilder(GtfsPathwayMode pathwayMode) {
return new GtfsPathway.Builder()
.setCsvRowNumber(2)
.setPathwayId("pathway1")
.setFromStopId("stop1")
.setToStopId("stop2")
.setPathwayMode(pathwayMode);
}

private static List<ValidationNotice> validationNoticesFor(GtfsPathway entity) {
NoticeContainer noticeContainer = new NoticeContainer();
new PathwayStairCountValidator().validate(entity, noticeContainer);
return noticeContainer.getValidationNotices();
}
}