Skip to content

Commit

Permalink
Merge pull request #3 from jsteenb2/feat/stack_frames_formatter
Browse files Browse the repository at this point in the history
feat: add formatter for StackFrames
  • Loading branch information
jsteenb2 authored Mar 17, 2024
2 parents 5200c02 + 744796d commit e675074
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 21 deletions.
11 changes: 0 additions & 11 deletions errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,17 +243,6 @@ func isT[T any](t *testing.T, v any) T {
return out
}

func isErr(t *testing.T, err error) bool {
t.Helper()

matches := err != nil
if !matches {
t.Fatalf("expected error:\n\t\tgot:\t%v", err)
}

return matches
}

func must(t *testing.T, outcome bool) {
t.Helper()

Expand Down
29 changes: 29 additions & 0 deletions frame.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,35 @@ func (f Frame) Format(s fmt.State, verb rune) {
// 2. add Formatter to be able to turn off the way it prints
type StackFrames []Frame

// String formats Frame to string.
func (f StackFrames) String() string {
var sb strings.Builder
sb.WriteString("[ ")

for i, frame := range f {
sb.WriteString(frame.String())
if i < len(f)-1 {
sb.WriteString(", ")
}
}
if sb.Len() > 2 {
sb.WriteString(" ")
}
sb.WriteString("]")
return sb.String()
}

// Format formats the frame according to the fmt.Formatter interface.
// See Frame.Format for the formatting rules.
func (f StackFrames) Format(s fmt.State, verb rune) {
for i, frame := range f {
frame.Format(s, verb)
if i < len(f)-1 {
io.WriteString(s, "\n\n")
}
}
}

func getFrame(skip FrameSkips) (Frame, bool) {
if skip == NoFrame {
return Frame{}, false
Expand Down
78 changes: 68 additions & 10 deletions frame_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,90 @@ import (
"github.com/jsteenb2/errors"
)

func TestStackTrace(t *testing.T) {
func TestStackTrace_SimpleError(t *testing.T) {
err := errors.New("some error")
isErr(t, err)

frames := errors.StackTrace(err)
must(t, eqLen(t, 1, frames))

sVal := fmt.Sprintf("%s", frames[0])
eq(t, "[ github.com/jsteenb2/errors/frame_test.go:11[TestStackTrace_SimpleError] ]", frames.String())

sVal := fmt.Sprintf("%s", frames)
eq(t, "frame_test.go", sVal)

sVal = fmt.Sprintf("%s", frames[0])
eq(t, "frame_test.go", sVal)

wantSPlusVal := `github.com/jsteenb2/errors_test.TestStackTrace
wantSPlusVal := `github.com/jsteenb2/errors_test.TestStackTrace_SimpleError
github.com/jsteenb2/errors/frame_test.go`

sPlusVal := fmt.Sprintf("%+s", frames[0])
sPlusVal := fmt.Sprintf("%+s", frames)
eq(t, wantSPlusVal, sPlusVal)

sPlusVal = fmt.Sprintf("%+s", frames[0])
eq(t, wantSPlusVal, sPlusVal)

dVal := fmt.Sprintf("%d", frames[0])
wantLine := "11"
dVal := fmt.Sprintf("%d", frames)
eq(t, wantLine, dVal)
dVal = fmt.Sprintf("%d", frames[0])
eq(t, wantLine, dVal)

vVal := fmt.Sprintf("%v", frames[0])
wantFile := "frame_test.go:11"
wantFile := "frame_test.go:" + wantLine
vVal := fmt.Sprintf("%v", frames)
eq(t, wantFile, vVal)
vVal = fmt.Sprintf("%v", frames[0])
eq(t, wantFile, vVal)

wantVPlusVal := `github.com/jsteenb2/errors_test.TestStackTrace
wantVPlusVal := `github.com/jsteenb2/errors_test.TestStackTrace_SimpleError
github.com/jsteenb2/errors/` + wantFile
vPlusVal := fmt.Sprintf("%+v", frames[0])
vPlusVal := fmt.Sprintf("%+v", frames)
eq(t, wantVPlusVal, vPlusVal)
vPlusVal = fmt.Sprintf("%+v", frames[0])
eq(t, wantVPlusVal, vPlusVal)
}

func TestStackTrace_WrappedError(t *testing.T) {
err := errors.Wrap(
errors.New("some error"),
)

frames := errors.StackTrace(err)
must(t, eqLen(t, 2, frames))

wantStr := "[ github.com/jsteenb2/errors/frame_test.go:54[TestStackTrace_WrappedError], github.com/jsteenb2/errors/frame_test.go:55[TestStackTrace_WrappedError] ]"
eq(t, wantStr, frames.String())

eq(t, "frame_test.go\n\nframe_test.go", fmt.Sprintf("%s", frames))
eq(t, "frame_test.go", fmt.Sprintf("%s", frames[0]))
eq(t, "frame_test.go", fmt.Sprintf("%s", frames[1]))

wantSPlusVal := `github.com/jsteenb2/errors_test.TestStackTrace_WrappedError
github.com/jsteenb2/errors/frame_test.go
github.com/jsteenb2/errors_test.TestStackTrace_WrappedError
github.com/jsteenb2/errors/frame_test.go`
eq(t, wantSPlusVal, fmt.Sprintf("%+s", frames))

wantSPlusVal = `github.com/jsteenb2/errors_test.TestStackTrace_WrappedError
github.com/jsteenb2/errors/frame_test.go`
eq(t, wantSPlusVal, fmt.Sprintf("%+s", frames[0]))
eq(t, wantSPlusVal, fmt.Sprintf("%+s", frames[1]))

eq(t, "54\n\n55", fmt.Sprintf("%d", frames))
eq(t, "54", fmt.Sprintf("%d", frames[0]))
eq(t, "55", fmt.Sprintf("%d", frames[1]))

wantFile := `frame_test.go:54
frame_test.go:55`
eq(t, wantFile, fmt.Sprintf("%v", frames))
eq(t, "frame_test.go:54", fmt.Sprintf("%v", frames[0]))
eq(t, "frame_test.go:55", fmt.Sprintf("%v", frames[1]))

wantVPlusFrame := `github.com/jsteenb2/errors_test.TestStackTrace_WrappedError
github.com/jsteenb2/errors/frame_test.go`
eq(t, wantVPlusFrame+":54\n\n"+wantVPlusFrame+":55", fmt.Sprintf("%+v", frames))
eq(t, wantVPlusFrame+":54", fmt.Sprintf("%+v", frames[0]))
eq(t, wantVPlusFrame+":55", fmt.Sprintf("%+v", frames[1]))
}

0 comments on commit e675074

Please sign in to comment.