assist_tests

package
v1.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 31, 2026 License: GPL-3.0 Imports: 14 Imported by: 0

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

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

func BinaryPath() (string, error)

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

func HardFailIfNotInTemp(t *testing.T, path string)

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

func MD5OfBytes(b []byte) string

MD5OfBytes is a small helper exposed for case authors / debug.

func SafeHomeDir

func SafeHomeDir(t *testing.T, prefix string) string

SafeHomeDir returns a tmp dir under os.TempDir() with the right shape for the harness. Bails the test if it can't create the dir.

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.

func LoadCases

func LoadCases(dir string) ([]Case, error)

LoadCases discovers all cases/*.yaml in the test data dir.

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 MockAgent

type MockAgent struct {
	ExitCode int    `yaml:"exit_code"`
	Stdout   string `yaml:"stdout"`
}

MockAgent overrides the default stub binary content for one agent.

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) Kill

func (s *TmuxSession) Kill()

Kill ends the tmux session unconditionally.

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

func (s *TmuxSession) WaitFor(substr string, timeout time.Duration) (string, bool)

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL