package wait import ( "os" "path/filepath" "testing" "time" ) func TestMetOnExitZero(t *testing.T) { calls := 0 run := func(cmd string) (string, int) { calls++ if calls < 3 { return "not ready", 1 } return "ready", 0 } res, err := Wait(Options{Cmd: "x", Interval: time.Millisecond, Timeout: time.Second}, run, nil) if err != nil { t.Fatal(err) } if !res.Met || res.Attempts != 3 || res.LastOut != "ready" { t.Errorf("unexpected result: %+v", res) } } func TestMatchesRequiredOnTopOfExitZero(t *testing.T) { calls := 0 run := func(cmd string) (string, int) { calls++ if calls == 1 { return "gitea starting", 0 // exit 0 but no match yet } return "gitea healthy", 0 } res, err := Wait(Options{Cmd: "x", Matches: "healthy", Interval: time.Millisecond, Timeout: time.Second}, run, nil) if err != nil { t.Fatal(err) } if !res.Met || res.Attempts != 2 { t.Errorf("match should gate success: %+v", res) } } func TestTimeoutReportsLastOutput(t *testing.T) { run := func(cmd string) (string, int) { return "still broken", 7 } res, err := Wait(Options{Cmd: "x", Interval: 5 * time.Millisecond, Timeout: 20 * time.Millisecond}, run, nil) if err != nil { t.Fatal(err) } if res.Met { t.Error("should have timed out") } if res.LastOut != "still broken" || res.LastExit != 7 { t.Errorf("last output lost: %+v", res) } if res.Attempts < 1 { t.Error("should have tried at least once") } } func TestBadRegexRejected(t *testing.T) { if _, err := Wait(Options{Cmd: "x", Matches: "("}, nil, nil); err == nil { t.Error("bad regex accepted") } } func TestEmptyCommandRejected(t *testing.T) { if _, err := Wait(Options{}, nil, nil); err == nil { t.Error("empty command accepted") } } // Integration: real shell, waiting for a file to appear (the exact // case from the agy live test in doc/tool-parity.md). func TestShellRunnerFileAppears(t *testing.T) { path := filepath.Join(t.TempDir(), "flag") go func() { time.Sleep(30 * time.Millisecond) os.WriteFile(path, []byte("x"), 0o644) }() res, err := Wait(Options{ Cmd: "test -f " + path, Interval: 10 * time.Millisecond, Timeout: 2 * time.Second, }, ShellRunner, nil) if err != nil { t.Fatal(err) } if !res.Met { t.Errorf("file never seen: %+v", res) } }