Skip to content

Instantly share code, notes, and snippets.

@sanketsudake
Last active December 26, 2025 13:12
Show Gist options
  • Select an option

  • Save sanketsudake/ce63ee952cc0b7bacb1bf9af67e8fba6 to your computer and use it in GitHub Desktop.

Select an option

Save sanketsudake/ce63ee952cc0b7bacb1bf9af67e8fba6 to your computer and use it in GitHub Desktop.
// Unit testing is an important part of writing
// principled Go programs. The `testing` package
// provides the tools we need to write unit tests
// and the `go test` command runs tests.
// For the sake of demonstration, this code is in package
// `main`, but it could be any package. Testing code
// typically lives in the same package as the code it tests.
package main
import (
"bytes"
"errors"
"fmt"
"strings"
"testing"
"github.com/gkampitakis/go-snaps/snaps"
)
// AggregateValidationErrors aggregates multiple errors into a single error
// Primary purpose is to print errors formatted via CLI for UX purposes.
func AggregateValidationErrors(objName string, err error) error {
if err == nil {
return nil
}
var errMsg bytes.Buffer
errMsg.WriteString(fmt.Sprintf("Invalid fission %s objects:\n", objName))
var unmaskError func(level int, err error)
// Do nested error unwrapping
unmaskError = func(level int, err error) {
unwrapper, ok := err.(interface {
Unwrap() []error
})
if ok {
for _, e := range unwrapper.Unwrap() {
unmaskError(level+1, e)
}
} else {
if level > 0 {
errMsg.WriteString(strings.Repeat(" ", level-1))
}
errMsg.WriteString(fmt.Sprintf("* %s\n", err.Error()))
}
}
unmaskError(0, err)
return errors.New(errMsg.String())
}
func TestAggregateValidationErrors(t *testing.T) {
for _, tc := range []struct {
name string
errs []error
}{
{
name: "no errors",
errs: []error{},
},
{
name: "one error",
errs: []error{
fmt.Errorf("E1"),
},
},
{
name: "multiple errors",
errs: []error{
fmt.Errorf("E1"),
fmt.Errorf("E2"),
fmt.Errorf("E3"),
},
},
{
name: "nested errors",
errs: []error{
fmt.Errorf("E1"),
errors.Join(
fmt.Errorf("E2"),
errors.Join(
fmt.Errorf("E3"),
fmt.Errorf("E4"),
),
),
fmt.Errorf("E5"),
errors.Join(
fmt.Errorf("E6"),
fmt.Errorf("E7"),
),
},
},
} {
t.Run(tc.name, func(t *testing.T) {
errs := errors.Join(tc.errs...)
aggErr := AggregateValidationErrors("Environment", errs)
snaps.MatchSnapshot(t, fmt.Sprint(aggErr))
})
}
t.Run("nil error", func(t *testing.T) {
aggErr := AggregateValidationErrors("Environment", nil)
snaps.MatchSnapshot(t, fmt.Sprint(aggErr))
})
t.Run("simple error", func(t *testing.T) {
aggErr := AggregateValidationErrors("Environment", fmt.Errorf("simple error"))
snaps.MatchSnapshot(t, fmt.Sprint(aggErr))
})
}
/* Sample snapshot from test
[TestAggregateValidationErrors/no_errors - 1]
<nil>
---
[TestAggregateValidationErrors/one_error - 1]
Invalid fission Environment objects:
* E1
---
[TestAggregateValidationErrors/multiple_errors - 1]
Invalid fission Environment objects:
* E1
* E2
* E3
---
[TestAggregateValidationErrors/nested_errors - 1]
Invalid fission Environment objects:
* E1
* E2
* E3
* E4
* E5
* E6
* E7
---
[TestAggregateValidationErrors/nil_error - 1]
<nil>
---
[TestAggregateValidationErrors/simple_error - 1]
Invalid fission Environment objects:
* simple error
---
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment