Skip to content

test(backend): Go CI workflow + first unit-test layer (Track B Phase 1) - #5

Merged
ghchinoy merged 1 commit into
mainfrom
track-b/phase1-ci-tests
Aug 14, 2026
Merged

ghchinoy merged 1 commit into
mainfrom
track-b/phase1-ci-tests

Conversation

@ghchinoy

Copy link
Copy Markdown
Owner

What

Track B Phase 1 — the code-health vertical-slice gate. Adds the Go CI workflow and the first layer of backend unit tests. Every later Track B phase is validated against this gate.

  • .github/workflows/go-test.yml — go build / go vet / go test on pull_request and push to main, mirroring sibling banana-weather (setup-go with go-version-file: backend/go.mod, cache-dependency-path: backend/go.sum, working-directory: backend).
  • backend/storage_test.go
    • addWavHeader — asserts RIFF/WAVE/fmt /data markers at their offsets, fileSize == len(data)+36, correct little-endian byteRate/blockAlign/sampleRate/bitsPerSample fields, and that the raw PCM payload is preserved verbatim.
    • generateFilename — extension inference (wav/ogg/default mp3), take- prefix, uniqueness across 1000 calls.
  • backend/generator_test.go
    • normalizeTags — each alias→canonical mapping, case-insensitivity, and no over-matching (already-canonical and non-tag substrings untouched). Written against behavior so it survives the planned Phase 3 regex hoist.

Why

Findings F6: the backend had no automated tests and no CI gate. This establishes both, table-driven and with no network / no GCP creds, matching the sibling repo's pattern.

Deferred

The JSON-repair path (generator.go handler: strip json fence → json.Unmarshal) is inline in a handler and not independently callable. Per the brief it is not refactored in this phase; it is deferred to the phase that touches that handler.

Scope

No production code or dependencies changed — test files + one workflow only. No model IDs / TTS logic touched (Track A boundary respected).

Local verification (cd backend)

$ go build ./...   # OK
$ go vet ./...     # OK
$ go test ./...
ok  	backend	0.020s

go test -v ./... — all subtests PASS:

  • TestAddWavHeader (3 subtests)
  • TestGenerateFilename (7 subtests, incl. uniqueness)
  • TestNormalizeTags (17 subtests)

…ase 1)

Vertical-slice gate for Track B code-health work.

- .github/workflows/go-test.yml: build/vet/test on pull_request + push
  to main, mirroring sibling banana-weather (setup-go with
  go-version-file: backend/go.mod, working-directory: backend).
- backend/storage_test.go: table-driven tests for addWavHeader (RIFF/
  WAVE/fmt /data markers, fileSize == len(data)+36, little-endian
  byteRate/blockAlign math) and generateFilename (extension inference,
  take- prefix, uniqueness across calls).
- backend/generator_test.go: table-driven tests for normalizeTags
  (alias->canonical mappings, case-insensitivity, no over-matching).
  Written against behavior so it survives the Phase 3 regex hoist.

JSON-repair path (generator.go handler) is inline/not independently
callable; deferred to the phase that touches that handler per the brief.

No production code or dependencies changed.
@ghchinoy

Copy link
Copy Markdown
Owner Author

PR #5 — Track B Phase 1 (CI workflow + Go unit tests) — Review

Executive Summary

Clean vertical-slice gate: one CI workflow mirroring banana-weather plus behavior-driven unit tests for addWavHeader, generateFilename, and normalizeTags. Risk: LOW. CI is green; no production code, deps, or model IDs touched.

Critical

None.

Required

None.

Nit / Optional

  • Optional — JSON-repair path (design P1 bullet) is not tested. The PR correctly explains it is inline in a handler and not independently callable, and defers it to the phase that touches that handler. Reasonable; noting for tracking so the design's P1 list is fully satisfied when that handler is refactored.

FYI

  • PR body says TestNormalizeTags has 17 subtests; the file defines 16. Cosmetic; no action.
  • go-version-file: backend/go.mod / cache-dependency-path: backend/go.sum are correctly repo-root-relative (the defaults.run.working-directory: backend applies only to run: steps, not the setup-go action inputs) — verified correct.

Positive Feedback

  • Tests are genuinely non-tautological: expected values are recomputed from inputs (byteRate, blockAlign, fileSize=dataLen+36, marker offsets) and checked against the real functions — a regression in addWavHeader would be caught.
  • normalizeTags test asserts observable behavior only (input→output over all 7 alias→canonical mappings, case-insensitivity, no over-matching on [sighs]/bare sigh), so it survives the Phase 3 regex hoist as intended. All 7 mappings match production exactly.
  • generateFilename covers MIME inference (wav/x-wav/ogg/default mp3), take- prefix, and a 1000-iteration uniqueness check.

Test Coverage

New code paths (all three target helpers) covered. Only gap is the deferred JSON-repair path, documented and justified.

Backward Compatibility

N/A — test files + one workflow only; no wire format, no production code.

Final Verdict

APPROVE

Gates run: verified PR diff via gh pr diff; gh pr checks → test: pass (1m31s) (go build/vet/test green in CI). Cross-checked each assertion against the actual generator.go/storage.go sources on the head ref via the GitHub API (non-destructive; no checkout of the shared tree). Could not run the Go toolchain locally — no checkout permitted per brief; CI covers the build/vet/test gate.

@ghchinoy
ghchinoy merged commit 4630755 into main Aug 14, 2026
1 check passed
@ghchinoy
ghchinoy deleted the track-b/phase1-ci-tests branch August 14, 2026 02:19
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