tests.test_metrics module¶
Tests for the metric registry, its store, its collectors and its charts.
- tests.test_metrics.STORE = PosixPath('/home/runner/work/repomatic/repomatic/docs/assets/metrics.csv')¶
This repository’s own readings, accrued by the scheduled sampler.
- tests.test_metrics.GITHUB_EPOCH = datetime.date(2008, 1, 1)¶
No star predates GitHub, so a reading dated earlier is a parsing fault.
Catches a store row holding a Unix timestamp where a calendar day belongs: seconds read as a day land in the 1970s, decades before any repository.
- tests.test_metrics.repo_config()[source]¶
Load this repository’s own
[tool.repomatic]section.- Return type:
- tests.test_metrics.test_registry_is_coherent()[source]¶
Check every metric is uniquely identified, sorted and documented.
- tests.test_metrics.test_chartable_metrics_are_exactly_the_accruing_ones()[source]¶
Check only a metric with a history is offered to a chart.
An attribute holds one current value, so plotting it would draw a curve through a single point.
- tests.test_metrics.test_every_source_is_ranked()[source]¶
Check the provenance vocabulary and its precedence stay in step.
An unranked source raises a
KeyErrorinsideupsert, mid-collection, on the one code path nobody watches.
- tests.test_metrics.test_record_round_trips_through_a_csv_row()[source]¶
Check a record survives the shape it is committed in.
- tests.test_metrics.test_upsert_is_idempotent_within_a_day()[source]¶
Check re-running on the same day overwrites rather than appends.
- tests.test_metrics.test_upsert_honors_source_precedence(stored, incoming, wins)[source]¶
Check a weaker provenance cannot overwrite a stronger one for a day.
- tests.test_metrics.test_an_accruing_metric_keeps_every_day()[source]¶
Check a counter’s past readings are all retained.
- tests.test_metrics.test_an_attribute_keeps_one_row_and_dates_the_change()[source]¶
Check an attribute holds a single row, restamped only when it moves.
A quiet week must leave the file untouched rather than restamping every row, and the surviving date is when the value last changed, which is what dates a dead project’s row honestly.
- tests.test_metrics.test_upsert_rejects_an_unregistered_metric()[source]¶
Check a typo in a metric ID fails loudly rather than storing a stray row.
- tests.test_metrics.test_save_metrics_writes_a_sorted_csv(tmp_path, history)[source]¶
Check the store is one row per reading, sorted for a readable diff.
- tests.test_metrics.test_save_metrics_writes_exactly_what_it_is_given(tmp_path)[source]¶
Check the file becomes the caller’s records, deletions included.
A collector re-deriving a whole curve has to be able to retire a reading it no longer dates, so the write cannot merge the file back under itself.
- tests.test_metrics.test_save_metrics_cannot_resurrect_a_pruned_attribute(tmp_path)[source]¶
Check a round trip through the file leaves an attribute one reading.
Loading, upserting and writing is what every collector does, and a superseded row surviving it would leave two readings of a metric that keeps one.
- tests.test_metrics.test_load_metrics_is_loud_on_a_corrupt_store(tmp_path)[source]¶
Check a malformed store raises instead of being silently clobbered.
- tests.test_metrics.test_load_metrics_tolerates_a_missing_store(tmp_path)[source]¶
Check a first run reads an empty store rather than failing.
- tests.test_metrics.test_collected_subjects_canonicalizes_and_marks_a_forerunner()[source]¶
Check a slug and a URL land on one spelling, forerunners tagged.
- tests.test_metrics.test_series_clips_a_forerunner_at_the_handover(history)[source]¶
Check a forerunner’s line stops where its successor’s begins.
The archived repository keeps collecting the odd star, and drawing that tail would run it the whole width of the chart beside its successor, reading as two live projects rather than one handover.
- tests.test_metrics.test_series_refuses_a_metric_with_no_history(history)[source]¶
Check charting an attribute is refused, naming what can be plotted.
- tests.test_metrics.test_series_skips_a_subject_with_no_reading()[source]¶
Check an unsampled subject is absent rather than an empty curve.
- tests.test_metrics.test_sample_subject_records_every_metric_and_the_origin(monkeypatch)[source]¶
Check one call yields each metric the forge answered, plus the birth.
- tests.test_metrics.test_sample_subject_adds_no_row_for_what_a_forge_did_not_answer(monkeypatch)[source]¶
Check a project with no release stores no blank release row.
- tests.test_metrics.test_sample_subject_survives_an_unreadable_forge(monkeypatch)[source]¶
Check one unreachable subject does not cost the others.
- tests.test_metrics.star_week(sunday, days)[source]¶
Build one week of the star-history endpoint’s payload.
- tests.test_metrics.test_reconstruct_accumulates_one_row_per_week_that_moved(monkeypatch)[source]¶
Check the daily buckets collapse into a cumulative weekly curve.
- tests.test_metrics.test_reconstruct_dates_a_day_without_converting_the_timezone(monkeypatch)[source]¶
Check a day is the week’s label plus its offset, left in GitHub’s zone.
The endpoint buckets days in
America/Los_Angeles. Itsweekfield is midnight UTC on the date labelling that local week, so the calendar date of that instant already carries the local day: converting it into a zone would shift every reading.
- tests.test_metrics.test_reconstruct_replaces_the_rows_it_wrote_before(monkeypatch)[source]¶
Check a re-derived curve drops the days its previous run had claimed.
The walk rebuilds the whole curve, so a day that no longer carries a reading must disappear rather than linger stating a total the rest of the curve contradicts. Rows from every other source are left alone.
- tests.test_metrics.test_reconstruct_skips_a_subject_off_github()[source]¶
Check a GitLab subject is skipped with a reason, not failed.
The star history is a GitHub endpoint; every other forge simply has nothing to reconstruct from.
- tests.test_metrics.test_reconstruct_reports_a_repository_that_is_gone(monkeypatch)[source]¶
Check a 404 on the first page reads as a skip, not a failure.
- tests.test_metrics.test_reconstruct_reports_a_repository_with_no_star(monkeypatch)[source]¶
Check an unstarred repository is a note, not an empty curve.
- tests.test_metrics.test_reconstruct_writes_nothing_when_pagination_breaks_midway(monkeypatch)[source]¶
Check a failure mid-walk abandons the subject rather than truncating.
The walk runs newest first, so a truncated one holds only recent weeks: totalling those would date a fraction of the stars as the whole history, and every point would look as legitimate as the rest.
- tests.test_metrics.test_reconstruct_gives_up_on_an_unparsable_page(monkeypatch)[source]¶
Check a payload that is not JSON abandons the subject.
- tests.test_metrics.test_reconstruct_walk_is_bounded(monkeypatch)[source]¶
Check a server that never runs out of pages cannot loop forever.
GitHub refuses past
STAR_HISTORY_MAX_PAGES, so the walk stops there on its own rather than trusting the endpoint to end the sequence.
- tests.test_metrics.test_palette_slots_are_distinct_and_two_toned()[source]¶
Check every categorical slot is its own hue in both themes.
- tests.test_metrics.test_assign_colors_is_positional_with_overrides_by_name()[source]¶
Check a subject keeps its slot, and a pinned hue wins over the palette.
- tests.test_metrics.test_assign_colors_refuses_to_cycle_the_palette()[source]¶
Check a chart bigger than the palette raises rather than repeating a hue.
- tests.test_metrics.test_assign_colors_rejects_a_malformed_override()[source]¶
Check an override that is not a light and dark pair is refused.
- tests.test_metrics.test_css_class(name, expected)[source]¶
Check a configured subject name folds into a usable CSS class.
- tests.test_metrics.test_build_chart_data_rejects_colliding_css_classes()[source]¶
Check two names folding onto one class are refused, not silently merged.
- tests.test_metrics.test_build_chart_data_is_loud_when_a_chart_plots_nothing()[source]¶
Check an unsampled chart names itself rather than drawing an empty box.
- tests.test_metrics.test_chart_spec_rejects_an_unknown_mode()[source]¶
Check a typo in
moderaises instead of silently drawing a calendar.
- tests.test_metrics.test_chart_spec_rejects_an_unknown_scale()[source]¶
Check a typo in
scaleraises instead of silently drawing a linear axis.
- tests.test_metrics.test_chart_spec_axes_are_independent()[source]¶
Check a comparison chart can slide the origins and compress the counts.
- tests.test_metrics.test_chart_spec_rejects_a_metric_with_no_history()[source]¶
Check a chart pointed at an attribute is refused at configuration time.
- tests.test_metrics.test_chart_spec_from_mapping()[source]¶
Check a configuration entry becomes a spec, shorthand included.
- tests.test_metrics.test_chart_spec_from_mapping_needs_an_output(entry)[source]¶
Check a chart with nowhere to write is refused.
- tests.test_metrics.test_chart_spec_from_mapping_rejects_a_scalar_only()[source]¶
Check an
onlythat is neither a string nor a list is refused.
- tests.test_metrics.test_render_chart_labels_every_series(history)[source]¶
Check the generator draws, labels and colours each plotted curve.
- tests.test_metrics.test_render_chart_caption_follows_the_plotted_metric(history)[source]¶
Check the axis names the metric rather than hard-coding stars.
- tests.test_metrics.test_render_chart_honors_a_series_subset(history)[source]¶
Check
onlydrops the peers, their forerunners included.
- tests.test_metrics.test_render_chart_relative_swaps_the_calendar_for_project_age(history)[source]¶
Check the by-age axis carries no calendar year among its ticks.
- tests.test_metrics.test_render_chart_logarithmic_axis_is_labelled_in_decades()[source]¶
Check the gridlines are powers of ten, and the caption says so.
- tests.test_metrics.test_render_chart_logarithmic_lifts_a_series_off_the_axis()[source]¶
Check the smaller curve stays readable beside one 440 times its size.
- tests.test_metrics.test_render_chart_logarithmic_keeps_a_zero_on_the_floor()[source]¶
Check a series carrying the created origin draws it, not drops it.
A count of zero has no logarithm, so it is placed on the floor the band at the bottom of the plot reserves. Dropping it instead would start each curve at its first star, which is a different and unstated claim. Not every series carries one: a repository starred on its creation day loses the anchor to that day’s measurement, per
repomatic.metrics.SOURCE_RANK.
- tests.test_metrics.test_render_chart_escapes_a_series_name()[source]¶
Check a name carrying markup cannot break out of the SVG text node.
- tests.test_metrics.test_render_chart_survives_a_flat_or_single_star_history(peak, logarithmic)[source]¶
Check a peak of 0 or 1 renders instead of dividing by zero.
A brand-new repository’s history is exactly this: the zero-star creation row alone, or that row plus its first star. Halving the axis step used to floor it to 0, and the ceiling division then crashed on both scales.
- tests.test_metrics.test_write_chart_is_convergent(tmp_path, history)[source]¶
Check redrawing an unmoved history rewrites nothing.
- tests.test_metrics.test_committed_store_is_well_formed()[source]¶
Check the readings this repository accrues keep their expected shape.
Guards a file a scheduled job appends to unattended: a duplicated reading, a subject that left the configuration, an unknown provenance or an attribute holding two rows would all surface here rather than as a misdrawn chart.