--- name: testing-marchat description: >- Writes and runs marchat tests with race detection, coverage, and dialect smoke patterns. Use when adding tests, fixing test failures, measuring coverage, or when the user mentions go test, -race, TESTING.md, or CI database smoke. paths: - "**/*_test.go" - "TESTING.md" --- # Testing marchat Authoritative tables and file list: `TESTING.md`. Do not weaken tests to make CI pass. ## Commands Main module (repo root). `developing-marchat` requires both plain and race runs after substantive changes: ```bash go test ./... go test -race ./... go test -coverprofile=mergedcoverage ./... go tool cover -func=mergedcoverage ``` Nested SDK (separate `go.mod`; not in root merged coverage): ```bash cd plugin/sdk && go test -coverprofile=sdkcover ./... && go tool cover -func=sdkcover ``` On Windows PowerShell, prefer a cover profile name without a `.out` suffix (e.g. `mergedcoverage`, `coverage`). Stale cache: ```bash go clean -cache -testcache ``` ## Patterns | Area | Pattern | |------|---------| | SQL / handlers | In-memory SQLite; table-driven cases in `server/*_test.go` | | Postgres / MySQL | `server/db_ci_smoke_test.go`; skip locally unless `MARCHAT_CI_POSTGRES_URL` / `MARCHAT_CI_MYSQL_URL` set; MySQL DSN uses `mysql:` or `mysql://` prefix | | Doctor env | `internal/doctor/env.go`: swap `osEnviron` under `environMu`; no `t.Parallel()` with other tests that swap it | | TUI client | Inject `tea.Msg`; no real terminal; `testmain_test.go` sets Lipgloss ANSI256 for SGR assertions | | Client render | `render_test.go`: URL wrap/hyperlink (headless); URL click/index helpers do not prove real-terminal opens; see `TESTING.md` Manual testing gaps | | cmd/server | Subprocess pattern in `cmd/server/subprocess_doctor_test.go` | | Plugins | `plugin/host/plugin_lifecycle_test.go` builds minimal plugin with `go build` | | Race | CI runs `go test -race ./...`; plugin host `StopPlugin` must drain readers before reuse | Set `MARCHAT_DOCTOR_NO_NETWORK=1` in tests that hit doctor update checks. ## Coverage - Main module overall statement coverage: see `README.md` and `TESTING.md` (regenerate; do not guess). - `plugin/sdk`: measure separately (see `TESTING.md`). - After material shifts (about 0.2% or new test files), update figures in `README.md` and `TESTING.md`. ## Anti-patterns (never do these) - Skipping `-race` or nested `plugin/sdk` module when relevant code changed - `time.Sleep` for synchronization without strong justification - Fudging assertions, deleting tests, or conditional passes (`if os.Getenv(...) { t.Skip() }` without CI contract) to green CI - Asserting only substring presence when ordering or side effects matter - Schema changes tested only on SQLite when dialect SQL diverges - Claiming tests pass without running `go test` on touched packages ## Checklist - [ ] New behavior has a focused test - [ ] `go test ./...` passes; `-race` when touching concurrency - [ ] `plugin/sdk` tested if SDK touched - [ ] `go test -coverprofile=mergedcoverage ./...` and refresh `README.md` / `TESTING.md` when totals shift materially (~0.2% or new test files) - [ ] Report actual `go test` outcome in the final response