You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
1.6 KiB
Go
87 lines
1.6 KiB
Go
2 years ago
|
package test
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/stretchr/testify/assert"
|
||
|
)
|
||
|
|
||
|
type Data[T, Y any] struct {
|
||
|
Name string
|
||
|
Input T
|
||
|
Want Y
|
||
|
E error
|
||
|
}
|
||
|
|
||
|
type Option[T, Y any] func(*Executor[T, Y])
|
||
|
type assertFn[Y any] func(t *testing.T, expected, actual Y) bool
|
||
|
|
||
|
func WithComparison[T, Y any](comparisonFn assertFn[Y]) Option[T, Y] {
|
||
|
return func(e *Executor[T, Y]) {
|
||
|
e.equalFn = comparisonFn
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type Executor[T, Y any] struct {
|
||
|
list []Data[T, Y]
|
||
|
equalFn assertFn[Y]
|
||
|
}
|
||
|
|
||
|
func NewExecutor[T, Y any](opt ...Option[T, Y]) *Executor[T, Y] {
|
||
|
e := &Executor[T, Y]{}
|
||
|
opt = append(opt, WithComparison[T, Y](func(t *testing.T, expected, actual Y) bool {
|
||
|
gotBytes, err := json.Marshal(actual)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
return false
|
||
|
}
|
||
|
wantBytes, err := json.Marshal(expected)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
return false
|
||
|
}
|
||
|
return assert.JSONEq(t, string(wantBytes), string(gotBytes))
|
||
|
}))
|
||
|
|
||
|
for _, o := range opt {
|
||
|
o(e)
|
||
|
}
|
||
|
return e
|
||
|
}
|
||
|
|
||
|
func (e *Executor[T, Y]) Add(data ...Data[T, Y]) {
|
||
|
e.list = append(e.list, data...)
|
||
|
}
|
||
|
|
||
|
func (e *Executor[T, Y]) Run(t *testing.T, do func(T) Y) {
|
||
|
if do == nil {
|
||
|
panic("execution body is nil")
|
||
|
return
|
||
|
}
|
||
|
for _, v := range e.list {
|
||
|
t.Run(v.Name, func(t *testing.T) {
|
||
|
inner := do
|
||
|
e.equalFn(t, v.Want, inner(v.Input))
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (e *Executor[T, Y]) RunE(t *testing.T, do func(T) (Y, error)) {
|
||
|
if do == nil {
|
||
|
panic("execution body is nil")
|
||
|
return
|
||
|
}
|
||
|
for _, v := range e.list {
|
||
|
t.Run(v.Name, func(t *testing.T) {
|
||
|
inner := do
|
||
|
got, err := inner(v.Input)
|
||
|
if v.E != nil {
|
||
|
assert.Equal(t, v.E, err)
|
||
|
return
|
||
|
}
|
||
|
e.equalFn(t, v.Want, got)
|
||
|
})
|
||
|
}
|
||
|
}
|