-
Notifications
You must be signed in to change notification settings - Fork 0
/
rest_tape_player_test.go
122 lines (107 loc) · 2.82 KB
/
rest_tape_player_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package router
import (
"encoding/json"
"fmt"
"reflect"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/Postcord/rest"
)
var _ rest.RESTClient = (*restTapePlayer)(nil)
type restTapePlayerTestStoreFatal struct {
*testing.T
fatal string
}
func (t *restTapePlayerTestStoreFatal) Fatal(args ...any) {
t.fatal = fmt.Sprint(args...)
}
func Test_restTapePlayer(t *testing.T) {
// Get all methods we wish to mock.
refImpl := reflect.TypeOf((*rest.Client)(nil))
numMethods := refImpl.NumMethod()
methods := make([]reflect.Method, numMethods)
for i := 0; i < numMethods; i++ {
methods[i] = refImpl.Method(i)
}
// Make sub-tests for all the methods.
for _, v := range methods {
t.Run(v.Name, func(t *testing.T) {
call := func(t *testing.T, overrun bool) {
// Define the tape item.
item := tapeItem{FuncName: v.Name}
// Create zero values for each of the params.
inCount := v.Type.NumIn()
if v.Type.IsVariadic() {
inCount--
}
in := make([]json.RawMessage, inCount-1)
zeroIn := make([]reflect.Value, inCount-1)
for i := 1; i < inCount; i++ {
x := v.Type.In(i)
n := reflect.New(x)
b, err := json.Marshal(n.Interface())
require.NoError(t, err)
in[i-1] = b
zeroIn[i-1] = n.Elem()
}
item.Params = in
// Create zero values for the return values.
outCount := v.Type.NumOut()
if outCount > 0 {
o := v.Type.Out(outCount - 1)
if _, ok := reflect.New(o).Interface().(*error); ok {
outCount--
}
}
out := make([]json.RawMessage, outCount)
for i := 0; i < outCount; i++ {
x := v.Type.Out(i)
b, err := json.Marshal(reflect.New(x).Interface())
require.NoError(t, err)
out[i] = b
}
item.Results = out
// Create the player.
var tester TestingT = t
startIndex := 0
if overrun {
tester = &restTapePlayerTestStoreFatal{T: t}
startIndex++
}
player := &restTapePlayer{
t: tester,
index: startIndex,
tape: []*tapeItem{&item},
}
// Do reflection on the player.
r := reflect.ValueOf(player)
// Check the method exists and call it.
m := r.MethodByName(v.Name)
if m.IsZero() {
t.Fatalf("method %s not found", v.Name)
}
res := m.Call(zeroIn)
if overrun {
// Check the fatal was thrown if this is an overrun.
assert.Equal(t, "unexpected "+v.Name+" at end of tape", tester.(*restTapePlayerTestStoreFatal).fatal)
} else {
// Check the results.
for _, x := range res {
if !x.IsZero() {
t.Errorf("%s is not zero", x.Type())
}
}
}
// Expect the index to be 1.
assert.Equal(t, 1, player.index)
}
t.Run("success", func(t *testing.T) {
call(t, false)
})
t.Run("overrun", func(t *testing.T) {
call(t, true)
})
})
}
}