Documentation
¶
Overview ¶
Package assist_tests is the tmux-driven harness for `sling assist` interactive flows.
File naming note: this file is intentionally NOT *_test.go because Go's test machinery would scope it to a single package. We want to import it from assist_test.go (same package) so the harness helpers are reusable across cases without being public API.
Invocation (from repo root, after building the binary):
cd cmd/sling && go build -o sling . SLING_BIN=$PWD/sling go test -v ./tests/assist
Or from this directory with a relative binary:
SLING_BIN=../../cmd/sling/sling go test -v .
Cases live in ./cases/*.yaml; fixtures in ./fixtures/.
Index ¶
- func ApplyFileAsserts(t *testing.T, homeDir string, asserts []FileAssert)
- func BinaryPath() (string, error)
- func HardFailIfNotInTemp(t *testing.T, path string)
- func MD5OfBytes(b []byte) string
- func SafeHomeDir(t *testing.T, prefix string) string
- type Case
- type FileAssert
- type MockAgent
- type Step
- type TmuxSession
- func (s *TmuxSession) Capture() string
- func (s *TmuxSession) CaptureStable(timeout time.Duration) string
- func (s *TmuxSession) CheckExitCode(want int, timeout time.Duration) error
- func (s *TmuxSession) Kill()
- func (s *TmuxSession) SendKey(key string)
- func (s *TmuxSession) SendLine(line string)
- func (s *TmuxSession) SendType(text string)
- func (s *TmuxSession) WaitFor(substr string, timeout time.Duration) (string, bool)
- func (s *TmuxSession) WriteDefaultMockAgents()
- func (s *TmuxSession) WriteMockAgent(name string, ma MockAgent)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ApplyFileAsserts ¶
func ApplyFileAsserts(t *testing.T, homeDir string, asserts []FileAssert)
ApplyFileAsserts runs the assert_files block after the case has finished.
func BinaryPath ¶
BinaryPath returns the absolute path to the freshly built sling binary. Default: ./sling relative to the process CWD (usually tests/assist/ when invoked as `go test .` from that dir, or set SLING_BIN to an absolute path).
Recommended: SLING_BIN=$PWD/cmd/sling/sling go test -v ./tests/assist
func HardFailIfNotInTemp ¶
HardFailIfNotInTemp panics if path doesn't live under os.TempDir(). Used as a belt-and-braces guard in case a test mishandles a path.
func MD5OfBytes ¶
MD5OfBytes is a small helper exposed for case authors / debug.
Types ¶
type Case ¶
type Case struct {
ID int // parsed from filename "NN.<name>.yaml"
Path string // absolute path to the YAML file
Name string `yaml:"name"`
Seed string `yaml:"seed"`
Env map[string]string `yaml:"env"`
// MockAgents overrides default stub agent scripts ($HOME/bin/<name>).
MockAgents map[string]MockAgent `yaml:"mock_agents"`
// NoMockAgents disables the harness's default stub-agent install. Use
// for cases that assert "no AI agent on $PATH" — otherwise the stubs
// trip codex's PATH-based Detect().
NoMockAgents bool `yaml:"no_mock_agents"`
TimeoutS int `yaml:"timeout_s"`
// Order is the sequence of tmux steps the harness drives. Named "order"
// (not "steps") to avoid colliding with pipeline/replication step
// terminology used elsewhere in this repo's YAML configs.
Order []Step `yaml:"order"`
AssertFiles []FileAssert `yaml:"assert_files"`
// AssertExitCode, when set, checks $? of the last shell command after
// all order steps complete (via echo of a unique marker).
AssertExitCode *int `yaml:"assert_exit_code"`
}
Case is one tmux-driven test scenario, loaded from cases/<NN>.<name>.yaml.
type FileAssert ¶
type FileAssert struct {
Path string `yaml:"path"`
Contains []string `yaml:"contains"`
MD5MatchesEmbedded bool `yaml:"md5_matches_embedded"`
IsRedirectTo string `yaml:"is_redirect_to"`
// NotEmpty only checks the file is non-empty (prefer this over a no-op
// md5 flag when embed comparison is not needed).
NotEmpty bool `yaml:"not_empty"`
}
FileAssert is a post-run filesystem check.
type Step ¶
type Step struct {
Run string `yaml:"run"`
SendKey string `yaml:"send_key"`
SendKeys []string `yaml:"send_keys"`
Type string `yaml:"type"`
WaitFor string `yaml:"wait_for"`
ExpectContains string `yaml:"expect_contains"`
ExpectNotContains string `yaml:"expect_not_contains"`
ExpectScreen string `yaml:"expect_screen"`
ExpectExit *int `yaml:"expect_exit"`
SleepMs int `yaml:"sleep_ms"`
TimeoutMs int `yaml:"timeout_ms"`
}
Step is one ordered action in the case script. The YAML uses one key per step type — exactly one of the fields below is populated.
type TmuxSession ¶
type TmuxSession struct {
Name string // session name, e.g. "sling-ai-01"
HomeDir string // ephemeral $HOME for this session
BinDir string // $HOME/bin (mock agents installed here)
Logger *bytes.Buffer
// contains filtered or unexported fields
}
TmuxSession owns one detached tmux session. Each case gets a fresh one.
func NewTmuxSession ¶
func NewTmuxSession(t *testing.T, name string, homeDir string, envOverrides map[string]string) *TmuxSession
NewTmuxSession spawns a fresh detached tmux session with a pinned 120x40 pane size, the given env, and a tmp $HOME. Caller MUST call Kill() in a defer to clean up (unless deliberately retaining the session).
func (*TmuxSession) Capture ¶
func (s *TmuxSession) Capture() string
Capture returns the current pane content as a single string.
func (*TmuxSession) CaptureStable ¶
func (s *TmuxSession) CaptureStable(timeout time.Duration) string
CaptureStable polls capture-pane until two consecutive snapshots match (Bubble Tea integration-test idiom) or timeout elapses. Returns the final snapshot.
func (*TmuxSession) CheckExitCode ¶
func (s *TmuxSession) CheckExitCode(want int, timeout time.Duration) error
CheckExitCode echoes $? with a unique marker and waits for the *expanded* form so we do not race the typed command line.
func (*TmuxSession) SendKey ¶
func (s *TmuxSession) SendKey(key string)
SendKey sends one named tmux key (e.g. Enter, Up, C-c).
func (*TmuxSession) SendLine ¶
func (s *TmuxSession) SendLine(line string)
SendLine sends a literal command followed by Enter.
func (*TmuxSession) SendType ¶
func (s *TmuxSession) SendType(text string)
SendType sends a literal string (no key interpretation), no Enter.
func (*TmuxSession) WaitFor ¶
WaitFor polls capture-pane until the substring appears or timeout elapses. Returns the matching snapshot, or the empty string on timeout.
func (*TmuxSession) WriteDefaultMockAgents ¶
func (s *TmuxSession) WriteDefaultMockAgents()
WriteDefaultMockAgents installs success-stubs for every CLI agent name so $PATH lookups don't fall through to a system-installed agent.
func (*TmuxSession) WriteMockAgent ¶
func (s *TmuxSession) WriteMockAgent(name string, ma MockAgent)
WriteMockAgent installs a stub script at $HOME/bin/<agent>. The stub echoes `[stub <agent>] <args>` then exits with the configured exit_code.