Files
summercms/tide/replay.go
Jakub Zych f6e1b892bc feat(02-01): record and replay one route through the summer CLI
- Add a generic tide flow schema with YAML fixture IO and HTTP record/replay
- Register parity:record and parity:replay on the bonfire summer tool
- Diff JSON scalars at $.path and non-JSON bodies at the changed byte offset

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 12:20:22 +02:00

49 lines
1.3 KiB
Go

package tide
import (
"context"
"fmt"
"strings"
)
// ReplayFlow executes each recorded step against target and diffs responses.
func ReplayFlow(ctx context.Context, flow Flow, cfg ReplayConfig) (Result, error) {
if err := validateFlow(flow); err != nil {
return Result{}, err
}
if strings.TrimSpace(cfg.Target) == "" {
return Result{}, fmt.Errorf("tide: replay target is required")
}
client := cfg.Client
if client == nil {
client = defaultClient()
}
limit := maxBody(cfg.MaxBody)
result := Result{OK: true, Steps: make([]StepResult, 0, len(flow.Steps))}
for _, step := range flow.Steps {
got, err := doStep(ctx, client, cfg.Target, step.Request, limit)
if err != nil {
return result, fmt.Errorf("tide: replay step %s: %w", step.ID, err)
}
sr := StepResult{ID: step.ID, OK: true}
if step.Response.Status != 0 && got.Status != step.Response.Status {
sr.OK = false
sr.Diffs = append(sr.Diffs, Diff{
Path: "status",
Expected: fmt.Sprintf("%d", step.Response.Status),
Actual: fmt.Sprintf("%d", got.Status),
})
}
sr.Diffs = append(sr.Diffs, compareBodies(step.Response, got)...)
if len(sr.Diffs) > 0 {
sr.OK = false
result.OK = false
}
result.Steps = append(result.Steps, sr)
}
if !result.OK {
return result, &MismatchError{Result: result}
}
return result, nil
}