Skip to content

Tests - #1

Merged
aaronbrethorst merged 17 commits into
developfrom
tests
Apr 22, 2026
Merged

Tests#1
aaronbrethorst merged 17 commits into
developfrom
tests

Conversation

@aaronbrethorst

@aaronbrethorst aaronbrethorst commented Apr 22, 2026

Copy link
Copy Markdown
Member
  • fix build breaks
  • Add unit tests
  • GitHub actions CI YAML

Summary by CodeRabbit

Release Notes

  • New Features

    • Added continuous integration pipeline with automated build validation and test execution
    • Implemented code coverage reporting to track test quality
  • Documentation

    • Added comprehensive development guide with build instructions and module overview
  • Tests

    • Expanded test coverage across core data models and utility functions
  • Build

    • Upgraded Java version to 17 and updated build configuration

Aligns the transitclockQuickStart module's Eclipse compiler
compliance/source/target with the Java 17 build (5d3ed0b); the
settings were still pinned to 1.7.
Documents the Maven multi-module layout, the Core → API (RMI) →
Webapp runtime pipeline, the shaded main classes under
org.transitclock.applications, and repo-specific gotchas (config
rev vs. travel-times rev, org.transitclock vs. legacy
org.transitime naming) so future Claude Code sessions can orient
without re-deriving it.
transitclockQuickStart's dependency:copy goal needs the API WAR,
which isn't produced by the test phase, so `mvn test` on the full
reactor fails. Recommend `mvn verify` instead and note the
single-module and exclude-QuickStart escape hatches.
The QuickStart test Hibernate config has carried raw <<<<<<<
/ ======= / >>>>>>> conflict markers since the original
transitclock/transitime merge (d8989115, e600fd30). That made the
XML unparseable, so every QuickStart test that loads it (four of
five) failed with "ConfigurationException: Unable to perform
unmarshalling at line number 0 and column 0".

Kept the HSQL side of the conflict — the file is named
hsql_hibernate.cfg.xml and the other side was postgres-targeted.
Two QuickStart tests cannot pass against current production code:

- TransiTimeTest drives GtfsFileProcessor, which calls
  System.exit(-1) from ~35 sites across org.transitclock.gtfs.*
  when it hits any processing error. That tears down the surefire
  fork before the test's try/catch can turn it into a normal
  failure. test_2_Core additionally hardcodes a Windows config
  path (C:\Users\Brendan\...).

- ApiJettyTest hardcodes port 8080, never stops Jetty (no
  @Before/@after), and asserts nothing meaningful. It fails on any
  host where 8080 is already bound.

@ignore'd with explanations rather than deleted so the intent is
preserved for whoever picks up the QuickStart smoke-test suite.
The remaining QuickStart tests (AppTest, CreateApiTest,
createWebAgencyTest) now pass and mvn verify goes green across
the reactor.
The shade plugin regenerates this file every package; it was
showing up as untracked after every build.
…asAdjuster

Establish a baseline of fast pure-Java unit tests for the highest-leverage
utility and value-type classes. Tests are pinned to current behavior —
including the quirks (e.g. MathUtils.max() seeded at 0, the non-arg
TemporalDifference.isWithinBounds() using strict <) — so future edits get
flagged rather than silently shifting.

97 tests across 7 files; mvn -pl transitclock test BUILD SUCCESS in ~3s.
Adds the JaCoCo plugin at the root aggregator so any module declaring
<parent> picks up instrumentation and per-module HTML reports at
target/site/jacoco/index.html during mvn verify. No coverage thresholds
yet — this is a baseline.

Note: transitclockApi and transitclockWebapp do not declare <parent>, so
they won't emit reports without further changes.
New coverage-report module runs jacoco:report-aggregate at the verify
phase, producing a single HTML report at
coverage-report/target/site/jacoco-aggregate/index.html that merges
transitclockCore, transitclockBarefootClient, and transitclockTraccarClient.

Skip JaCoCo in transitclockQuickStart: it bundles api.war and web.war
into target/classes as resources, and JaCoCo's analyzer chokes on the
multi-release JARs inside the WARs ("Can't add different class with
same name"). QuickStart is a launcher, not something worth measuring
coverage on, so it's excluded from the aggregate as well.
Adds a short Code Coverage section to the README and a more detailed
one to CLAUDE.md, covering per-module reports, the aggregate in
coverage-report/, why QuickStart is skipped, and which modules don't
inherit the plugin.
…uleTime

These db.structs classes are mostly pure-Java value types with small
amounts of math and bookkeeping — they don't need a DB or Hibernate
context to construct. The tests lock down:

- Location: equals/hashCode on lat/lon, distance delegations, toString.
- Vector: length, distance and match-distance pass-throughs, cardinal
  heading() and angle() conventions, beginning/end/middle/locAlongVector
  slicing, zero-length handling.
- VectorWithHeading: 0-360 normalization (which plain Vector does not do)
  and headingOK delegation.
- Extent: ±infinity initial bounds, add(Location)/add(Extent) expansion,
  equals/hashCode, and isWithinDistance with a small meter buffer.
- ScheduleTime: getTime() precedence (departure over arrival, fallback to
  arrival, null when both missing) and toString field-presence behavior.

39 new tests; mvn -pl transitclock test BUILD SUCCESS. Per-class coverage
ranges from 73% (VectorWithHeading) to 93% (Location); aggregate still
reads 2% because these classes are small relative to the 142k-instruction
transitclockCore bundle.
Extend db.structs coverage into entity-shaped classes that are mostly
testable without a Hibernate session or live Core.

- AvlReport (24 tests): constructor variants (lat/lon vs Location, NaN
  speed/heading becoming "invalid", source truncated to SOURCE_LENGTH,
  no-speed overload), getHeading's low-speed NaN rule, latency zero
  when unprocessed, AssignmentType predicates (block-type covers both
  regular and sched-based variants), setAssignment null-guard, and the
  validateData happy/unhappy paths. setTimeProcessed requires Core, so
  the positive-latency path is left alone with a comment.
- Headway (4 tests): Headway's public constructor pulls configRev from
  Core, so the tests go through the no-arg Hibernate constructor plus
  setters. Equality only considers headway + five id fields — timing
  and stats don't participate.
- Calendar (8 tests): GTFS-style "1" means true and everything else
  (including nulls and "yes"/"true") is false; trimmed " 1 " still
  counts. End date is configured-end + 1 day. Round-trip of string
  formatters and composite-id equals/hashCode.
- ActiveRevisions (4 tests): default -1/-1 sentinels, setters,
  isValid() requires BOTH revisions non-negative, toString.

40 tests, all green. Aggregate coverage for the targeted classes is
now: Headway 77%, Calendar 61%, AvlReport 52%, ActiveRevisions 39%.
…Stop

Continues filling in structs-package coverage. HoldingTime uses reflection to
set the final holdingTime field so getTimeToLeave/leaveStop can be exercised
without going through the Core-dependent value constructors. Stop uses
GtfsStop's plain-args constructor with a null-file TitleFormatter so no CSV
parsing is needed.
These structs take Gtfs* records whose only public constructor reads a
CSVRecord, so each test stages a single-row CSV in memory via CSVFormat
+ CSVParser. Agency's Extent is exercised with an empty route list. FareRule
tests pin the "empty-string internal, null-on-read" contract for its
composite-id columns and the properRouteId override path.
MonitoringEvent, Prediction, PredictionAccuracy, PredictionForStopPath,
TravelTimesForStopPath, TravelTimesForTrip, VehicleState

Frequency/CalendarDate use in-memory CSVRecord staging; Match/Prediction/
PredictionAccuracy/MonitoringEvent reach their Hibernate no-arg constructors
(protected in same package, private via reflection where needed), with
field mutation via reflection to exercise equals/hashCode and Lifecycle
intern-on-load. TravelTimesForTrip pins the documented "equals ignores
tripCreatedForId" behavior that's load-bearing for the travel-time cache.
Builds the reactor with `mvn -B -ntp verify` on push/PR to develop, main, and
master. Uses JDK 17 Temurin and caches Maven artifacts. Publishes the JaCoCo
aggregate report always and surefire reports on failure.
@coderabbitai

coderabbitai Bot commented Apr 22, 2026

Copy link
Copy Markdown

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

This PR adds comprehensive test coverage for database structs and utility classes, establishes JaCoCo code coverage aggregation through a new Maven module, configures CI/CD via GitHub Actions, and provides build/test documentation. Additionally, it updates Eclipse project settings to Java 17 and marks certain integration tests as ignored.

Changes

Cohort / File(s) Summary
CI/CD Infrastructure
.github/workflows/ci.yml
Adds GitHub Actions CI workflow triggering on push/PR to develop/main/master branches, running Maven verify with JDK 17, and conditionally uploading JaCoCo coverage reports and test artifacts.
Code Coverage Aggregation
coverage-report/pom.xml, coverage-report/.gitignore
Introduces new aggregator Maven module producing combined JaCoCo HTML reports across Core and client modules via jacoco-maven-plugin report-aggregate goal.
Build Configuration Updates
pom.xml, transitclockQuickStart/pom.xml
Adds coverage-report module to parent POM and includes module in include-integration-tests profile; configures jacoco-maven-plugin at parent level; skips coverage in QuickStart module.
Project Documentation
CLAUDE.md, README.md
Adds comprehensive Claude AI guidance covering multi-module build, test execution, integration test profiles, JaCoCo configuration, and system architecture; documents code coverage report locations.
Ignore Rules
transitclock/.gitignore
Adds dependency-reduced-pom.xml to ignored patterns.
Core Logic Tests
transitclock/src/test/java/org/transitclock/core/IndicesTest.java, ...TemporalDifferenceTest.java, .../bias/BiasAdjusterTest.java
Adds comprehensive test suites for Indices comparison/predicate behavior, TemporalDifference construction/arithmetic/bounds logic, and LinearBiasAdjuster/ExponentialBiasAdjuster implementations.
Database Struct Tests
transitclock/src/test/java/org/transitclock/db/structs/{ActiveRevisionsTest, AgencyTest, AvlReportTest, CalendarDateTest, CalendarTest, ConfigRevisionTest, ExtentTest, FareAttributeTest, FareRuleTest, FrequencyTest, HeadwayTest, HoldingTimeTest, LocationTest, MatchTest, MeasuredArrivalTimeTest, MonitoringEventTest, PredictionAccuracyTest, PredictionForStopPathTest, PredictionTest, ScheduleTimeTest, StopTest, TransferTest, TravelTimesForStopPathTest, TravelTimesForTripTest, VectorTest, VectorWithHeadingTest, VehicleStateTest}.java
Adds 27 test classes validating constructor round-tripping, getter behavior, equals/hashCode semantics, toString formatting, and domain-specific logic (e.g., timezone caching, GTFS parsing, optional field handling) for database entity structs.
Utility Tests
transitclock/src/test/java/org/transitclock/utils/{GeoTest.java, MathUtilsTest.java, StringUtilsTest.java, TimeTest.java}
Adds test coverage for geospatial distance/vector calculations, mathematical rounding/aggregation, string formatting/sorting, and time-of-day parsing/formatting utilities.
Eclipse & QuickStart Configuration
transitclockQuickStart/.settings/org.eclipse.jdt.core.prefs, transitclockQuickStart/src/test/java/org/transitclock/config/{ApiJettyTest.java, TransiTimeTest.java}, transitclockQuickStart/src/test/resources/hsql_hibernate.cfg.xml
Updates Eclipse compiler settings from Java 7 to Java 17; annotates ApiJettyTest and TransiTimeTest with @Ignore to prevent execution; removes Git conflict markers from Hibernate config file.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title "Tests" is vague and generic, failing to convey the specific nature or scope of the changes made in this substantial pull request. Use a more descriptive title that captures the main objective, such as "Add comprehensive unit tests, CI workflow, and JaCoCo coverage reporting" or "Add unit tests and GitHub Actions CI with JaCoCo coverage."
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@aaronbrethorst
aaronbrethorst merged commit 9eb8642 into develop Apr 22, 2026
2 of 3 checks passed
@aaronbrethorst
aaronbrethorst deleted the tests branch April 22, 2026 05:22
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.

1 participant