test.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package test
  2. import (
  3. "encoding/json"
  4. "testing"
  5. "github.com/stretchr/testify/assert"
  6. )
  7. type Data[T, Y any] struct {
  8. Name string
  9. Input T
  10. Want Y
  11. E error
  12. }
  13. type Option[T, Y any] func(*Executor[T, Y])
  14. type assertFn[Y any] func(t *testing.T, expected, actual Y) bool
  15. func WithComparison[T, Y any](comparisonFn assertFn[Y]) Option[T, Y] {
  16. return func(e *Executor[T, Y]) {
  17. e.equalFn = comparisonFn
  18. }
  19. }
  20. type Executor[T, Y any] struct {
  21. list []Data[T, Y]
  22. equalFn assertFn[Y]
  23. }
  24. func NewExecutor[T, Y any](opt ...Option[T, Y]) *Executor[T, Y] {
  25. e := &Executor[T, Y]{}
  26. opt = append(opt, WithComparison[T, Y](func(t *testing.T, expected, actual Y) bool {
  27. gotBytes, err := json.Marshal(actual)
  28. if err != nil {
  29. t.Fatal(err)
  30. return false
  31. }
  32. wantBytes, err := json.Marshal(expected)
  33. if err != nil {
  34. t.Fatal(err)
  35. return false
  36. }
  37. return assert.JSONEq(t, string(wantBytes), string(gotBytes))
  38. }))
  39. for _, o := range opt {
  40. o(e)
  41. }
  42. return e
  43. }
  44. func (e *Executor[T, Y]) Add(data ...Data[T, Y]) {
  45. e.list = append(e.list, data...)
  46. }
  47. func (e *Executor[T, Y]) Run(t *testing.T, do func(T) Y) {
  48. if do == nil {
  49. panic("execution body is nil")
  50. return
  51. }
  52. for _, v := range e.list {
  53. t.Run(v.Name, func(t *testing.T) {
  54. inner := do
  55. e.equalFn(t, v.Want, inner(v.Input))
  56. })
  57. }
  58. }
  59. func (e *Executor[T, Y]) RunE(t *testing.T, do func(T) (Y, error)) {
  60. if do == nil {
  61. panic("execution body is nil")
  62. return
  63. }
  64. for _, v := range e.list {
  65. t.Run(v.Name, func(t *testing.T) {
  66. inner := do
  67. got, err := inner(v.Input)
  68. if v.E != nil {
  69. assert.Equal(t, v.E, err)
  70. return
  71. }
  72. e.equalFn(t, v.Want, got)
  73. })
  74. }
  75. }