Skip to content

feat: Add shapes.txt validator#2123

Open
cswilson252 wants to merge 24 commits intoMobilityData:masterfrom
cswilson252:noShapesNoDrt
Open

feat: Add shapes.txt validator#2123
cswilson252 wants to merge 24 commits intoMobilityData:masterfrom
cswilson252:noShapesNoDrt

Conversation

@cswilson252
Copy link
Copy Markdown
Contributor

@cswilson252 cswilson252 commented Mar 4, 2026

Summary:

Add validator that checks if either a shapes.txt and/or a fixed or zone-based DRT service is present (as per #1792)

DRT functionality added as per this reference

Fixes #1792

Expected behavior:

Validator will print WARNING if shapes.txt and signs of a DRT feature are not found.

Please make sure these boxes are checked before submitting your pull request - thanks!

  • Run the unit tests with gradle test to make sure you didn't break anything
  • Format the title like "feat: [new feature short description]". Title must follow the Conventional Commit Specification(https://www.conventionalcommits.org/en/v1.0.0/).
  • Linked all relevant issues

@cswilson252 cswilson252 marked this pull request as ready for review March 9, 2026 00:28
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new validator intended to warn when shapes.txt is missing unless the feed appears to use zone-based or fixed-stop DRT (per #1792).

Changes:

  • Introduces MissingShapesFileValidator and a corresponding test class.
  • Adds unit tests covering shapes present + DRT present scenarios (and a no-shapes/no-DRT scenario).
  • Adds an extra import in ShapeUsageValidator.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 9 comments.

File Description
main/src/main/java/org/mobilitydata/gtfsvalidator/validator/MissingShapesFileValidator.java New multi-file validator for warning on missing shapes.txt unless DRT indicators are present.
main/src/test/java/org/mobilitydata/gtfsvalidator/validator/MissingShapesFileValidatorTest.java New unit tests for the validator behavior.
main/src/main/java/org/mobilitydata/gtfsvalidator/validator/ShapeUsageValidator.java Adds an import for a nested notice type.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@cswilson252
Copy link
Copy Markdown
Contributor Author

i'm a bit stuck as to why the test failure is happening

@davidgamez davidgamez self-requested a review April 27, 2026 17:30
Comment on lines +67 to +73
for (GtfsStopTime stopTime : stopTimeTable.getEntities()) {
noticeContainer.addValidationNotice(
new MissingRecommendedFileNotice("shapes.txt"));
// This is a feed-level warning; emit it at most once.
break;
}
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This loop looks unnecessary, and the noticeContainer.addValidationNotice method is called once and immediately after the break exits.
Also, if stop_times.txt is empty or missing, the loop body never runs, and no notice is emitted, even when it should be.

assertThat(missingRecommendedFileNoticesCount).isAtLeast(1);
}

private static List<ValidationNotice> generateNotices(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

testNoShapesFileAndNoDrtPresent fails because generateNotices() ignores the shapeContainer parameter. It always builds the shape container via forEntities(shapes,), which gives status PARSABLE_HEADERS_AND_ROWS, not MISSING_FILE. So isMissingFile() always returns false, and no notice is ever emitted.

}

@Override
public void validate(NoticeContainer noticeContainer) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] Reuse FeedMetadata logic instead of re-implementing it

The DRT detection logic already exists in FeedMetadata:

  • hasAtLeastOneTripWithOnlyLocationId(), zone-based DRT check
  • hasAtLeastOneTripWithOnlyLocationGroupId() + hasAtLeastOneRecordInFile(), fixed-stops DRT check (mirrors loadFixedStopsDemandResponseTransit)

To reuse them in MissingShapesFileValidator, these three methods need to be made public static and their signatures updated to accept the individual table containers directly (e.g. GtfsStopTimeTableContainer and GtfsLocationGroupsTableContainer).

This avoids duplicating the DRT detection logic and ensures the validator stays consistent with how features are detected elsewhere in the codebase. It would also make the validate() method read clearly:

 boolean hasZoneBasedDrt = FeedMetadata.hasAtLeastOneTripWithOnlyLocationId(stopTimeTable);
 boolean hasFixedStopsDrt = FeedMetadata.hasAtLeastOneRecordInFile(locationGroupsTable)
     && FeedMetadata.hasAtLeastOneTripWithOnlyLocationGroupId(stopTimeTable);
 
 if (shapeTable.isMissingFile() && !hasZoneBasedDrt && !hasFixedStopsDrt) {
     noticeContainer.addValidationNotice(new MissingRecommendedFileNotice("shapes.txt"));
 }

Alternative: add hasZoneBasedDemandResponseService and hasFixedStopsDemandResponseService to FeedMetadata


@Override
public void validate(NoticeContainer noticeContainer) {
Boolean missingShapes = shapeTable.isMissingFile();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the file is present, we can add a return statement to save execution time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add shapes.txt as recommended file

3 participants