Documentation
¶
Overview ¶
Package crossfixture supplies the shared scaffolding for tests that must verify TUI ↔ web ↔ CLI parity (TEST-PLAN.md §6.4 / TUI-TEST-PLAN.md §6.4 crossProcessFixture).
The harness is intentionally driver-agnostic — it owns the *isolation* (HOME, ~/.agent-deck, env vars, optional binary path, optional web base URL) and the *parity check* (deep-equal of three snapshots). Concrete tests bring their own web Server / CLI binary / TUI driver.
Why this shape:
- Booting `internal/web.Server` requires non-trivial wiring (MenuData, push, cost store) that varies by test.
- Wiring teatest into a concrete *Home is intrusive and lives in internal/ui where this package can't reach without an import cycle.
So the fixture exposes hooks rather than auto-wired clients.
Usage:
cf := crossfixture.New(t, crossfixture.Options{Profile: "test"})
srv := bootMyWebServer(cf.AgentDeckDir)
cf.AttachWeb(srv.URL)
cf.AttachCLI(buildBinary(t))
web := cf.MustGetBytes(t, "/api/sessions")
cli, _ := cf.RunCLI("list", "--json")
cf.AssertParity(t, crossfixture.Snapshots{CLI: cli, Web: web, TUI: web})
Index ¶
- type Fixture
- func (f *Fixture) AssertParity(t TB, s Snapshots)
- func (f *Fixture) AttachCLI(binaryPath string)
- func (f *Fixture) AttachWeb(baseURL string)
- func (f *Fixture) GetJSON(t TB, path string, out any)
- func (f *Fixture) MustGetBytes(t TB, path string) []byte
- func (f *Fixture) RunCLI(args ...string) ([]byte, error)
- type Options
- type Snapshots
- type TB
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Fixture ¶
type Fixture struct {
Home string // HOME for this test
AgentDeckDir string // <Home>/<AgentDeckSubdir>
WebURL string // empty until AttachWeb
CLIBinary string // empty until AttachCLI
// contains filtered or unexported fields
}
Fixture is the live test scaffold.
func New ¶
New seeds env (HOME, AGENTDECK_PROFILE) under t.Setenv (auto-restored) and creates the agent-deck data dir.
func (*Fixture) AssertParity ¶
AssertParity fails the test if any two non-nil snapshots disagree byte-for-byte. The error message lists every snapshot so the divergence is one glance.
func (*Fixture) AttachCLI ¶
AttachCLI records the path of an already-built agent-deck binary. Tests build it once via testing.Main / TestMain (or share a binary across tests) and pass the path here so RunCLI can exec it under the fixture's isolated env.
func (*Fixture) AttachWeb ¶
AttachWeb records the base URL of an already-started web server. Tests stand the server up themselves (so they control the wiring of MenuData / pushService / SessionMutator); the fixture just remembers the URL for GetJSON / GetBytes calls.
func (*Fixture) GetJSON ¶
GetJSON GETs the path under WebURL and decodes into out. Fails the test on transport / decode errors.
func (*Fixture) MustGetBytes ¶
MustGetBytes returns the response body for GET WebURL+path or fails.
type Options ¶
type Options struct {
// Profile sets AGENTDECK_PROFILE for both the in-process server and
// the CLI subprocess. Empty leaves it unset.
Profile string
// AgentDeckSubdir is the relative path under HOME where ~/.agent-deck
// lives. Defaults to ".agent-deck" — override only when emulating
// non-standard installs.
AgentDeckSubdir string
}
Options controls how the fixture seeds the environment.
type Snapshots ¶
Snapshots is the three-way parity input. Tests fill in whichever channels they exercised; nil entries are skipped during AssertParity.
The expected shape is "the canonical JSON representation of the same observable" — e.g. all three should be the deep-equal session-list JSON after sort. Tests are responsible for normalizing (sorting, stripping volatile fields like timestamps).