Skip to content

test: add coverage for internal/analytics + binder-ambiguity fix (#8) - #16

Merged
detour1999 merged 1 commit into
mainfrom
test/analytics-coverage
Aug 3, 2026
Merged

test: add coverage for internal/analytics + binder-ambiguity fix (#8)#16
detour1999 merged 1 commit into
mainfrom
test/analytics-coverage

Conversation

@detour1999

@detour1999 detour1999 commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #8.

First tests for the `internal/analytics` package. Also carries a small incidental fix to `queries.go` that the tests surfaced.

What's tested

Real SQLite fixture → real parquet export → real DuckDB queries. No mocks.

  • `Exporter.Export` — parquet round-trip produces a non-empty file at the expected path
  • `SessionsParquetHasSource` — missing file → false; fresh file → true; synthetic legacy file (pre-feat: plugin architecture for multi-source session support #6 schema, no source column) → false
  • `GetSummary`, `GetTokensByDay`, `GetTopProjects`, `GetTokensByModel` — full query coverage over a multi-source fixture; aggregations verified against known totals
  • `GetTokensBySource`, `GetSessionsBySource` — multi-source aggregation
  • Missing-cache error paths for all six query methods
  • Legacy parquet + source query → clean error (not misleading rows)

The legacy-parquet tests use a synthetic `legacySessionRecord` written directly via `parquet-go` to simulate a pre-multi-source cache.

Incidental fix

The `COALESCE(source, 'claude-code') as source ... GROUP BY COALESCE(source, ...)` fallback in `GetTokensBySource`/`GetSessionsBySource` was aspirational: on a legacy parquet without a source column, DuckDB's binder shadowed the missing column with the SELECT alias named `source` and errored inside the COALESCE with a confusing message.

Renamed the alias to `source_out` and switched to `GROUP BY 1` so the error is now the honest "Referenced column source not found in FROM clause." `rows.Scan` is positional, so Go-side struct mapping is unchanged.

The COALESCE fallback still can't rescue legacy parquets (DuckDB errors at bind-time regardless), but callers hit the `SessionsParquetHasSource + rebuild` guard in the TUI before running these queries. The test suite documents this.

Test plan

  • 12 new tests passing
  • Full suite green under `-race -count=1`

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Summary by CodeRabbit

  • Bug Fixes

    • Improved analytics queries for compatibility with both current and legacy session data.
    • Fixed source-based token and session breakdowns when analyzing older cached data.
    • Improved handling of missing or incompatible analytics data, with clearer failure behavior.
  • Tests

    • Expanded coverage for analytics exports, summaries, daily trends, and breakdowns by project, model, and source.

First tests for the analytics package, covering:

- Exporter.Export — parquet round-trip produces a non-empty file
- SessionsParquetHasSource — missing file / fresh file / synthetic legacy
  file (schema-compat detection added in PR #6)
- GetSummary / GetTokensByDay / GetTopProjects / GetTokensByModel — full
  query coverage over a multi-source fixture; aggregations verified
  against known totals
- GetTokensBySource / GetSessionsBySource — multi-source aggregation
- Missing-cache error paths for all query methods

Includes a synthetic legacyParquetRecord (pre-#6 schema without the
source column) written directly via parquet-go to exercise the
schema-compat detection and the legacy-parquet source-query error path.

## Incidental fix (queries.go)

The COALESCE(source, 'claude-code') fallback in GetTokensBySource and
GetSessionsBySource was aspirational: on a legacy parquet without a
source column, the previous SQL

    SELECT COALESCE(source, ...) as source
    FROM read_parquet(...)
    GROUP BY COALESCE(source, ...)

triggered a confusing DuckDB binder error about aliases being illegal in
GROUP BY expressions, because DuckDB shadowed the missing column with
the SELECT alias named `source`.

Renamed the alias to `source_out` and switched to `GROUP BY 1` so the
error surface is now honest: "Referenced column source not found in FROM
clause" — actionable for anyone bypassing the SessionsParquetHasSource
+ rebuild guard in the TUI. rows.Scan is positional so the Go-side
struct field mapping is unchanged.

Fixes #8
@detour1999
detour1999 merged commit 1b70cd1 into main Aug 3, 2026
6 of 7 checks passed
@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f12925cd-0cdd-4201-a10d-90ba7efeafa4

📥 Commits

Reviewing files that changed from the base of the PR and between 87e0b23 and 302bb23.

📒 Files selected for processing (2)
  • internal/analytics/analytics_test.go
  • internal/analytics/queries.go

Walkthrough

Analytics tests now use SQLite, Parquet, and DuckDB fixtures. They verify exports, schema detection, aggregations, legacy-cache behavior, and missing-cache errors. Source queries now use explicit aliases and positional grouping for legacy Parquet compatibility.

Changes

Analytics coverage and compatibility

Layer / File(s) Summary
Analytics fixtures and Parquet schema coverage
internal/analytics/analytics_test.go
Tests seed varied sessions, verify Parquet export, and detect current, legacy, and missing cache schemas.
Source query compatibility
internal/analytics/queries.go, internal/analytics/analytics_test.go
Source token and session queries use source_out with positional grouping. Legacy-cache tests verify source-query errors.
Aggregation and cache error validation
internal/analytics/analytics_test.go
Integration tests validate summary, daily, project, model, and source aggregations. Missing-cache tests verify error returns.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Poem

A rabbit checks each cache with care,
Parquet rows hop everywhere.
Sources group by names anew,
Legacy paths behave as due.
Missing files now raise a sound—
Clean analytics all around!

✨ 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 test/analytics-coverage

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

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 unit tests for internal/analytics package (0% coverage)

1 participant