charmbracelet / x

Charm experimental packages
MIT License
115 stars 12 forks source link

Show final output when teatest.WaitFor fails #116

Closed mhmd-azeez closed 2 weeks ago

mhmd-azeez commented 2 weeks ago

Is your feature request related to a problem? Please describe. It's very hard to debug teatest.WaitFor failures due to timeout. You have no idea where it's stuck. So you have to resort to trial & error. I am happy to send a PR to fix this

Describe the solution you'd like Print the final output in the error message

Describe alternatives you've considered I am currently using a patched version of WaitFor

Additional context Add any other context or screenshots about the feature request here.


func WaitFor(
    tb testing.TB,
    r io.Reader,
    condition func(bts []byte) bool,
    options ...teatest.WaitForOption,
) {
    tb.Helper()
    if err := doWaitFor(r, condition, options...); err != nil {
        tb.Fatal(err)
    }
}

func doWaitFor(r io.Reader, condition func(bts []byte) bool, options ...teatest.WaitForOption) error {
    wf := teatest.WaitingForContext{
        Duration:      time.Second,
        CheckInterval: 50 * time.Millisecond, //nolint: gomnd
    }

    for _, opt := range options {
        opt(&wf)
    }

    var b bytes.Buffer
    start := time.Now()
    for time.Since(start) <= wf.Duration {
        if _, err := io.ReadAll(io.TeeReader(r, &b)); err != nil {
            return fmt.Errorf("WaitFor: %w", err)
        }
        if condition(b.Bytes()) {
            return nil
        }
        time.Sleep(wf.CheckInterval)
    }

    // This is the important part
    return fmt.Errorf("WaitFor: condition not met after %s. Last output:\n%s", wf.Duration, b.String())
}
caarlos0 commented 2 weeks ago

yeah, that would be a good one!

I am happy to send a PR to fix this

awesome, please do 🙏