-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils_test.go
117 lines (94 loc) · 2.82 KB
/
utils_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
package tusd_test
import (
"fmt"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"reflect"
"testing"
"github.com/golang/mock/gomock"
"github.com/tus/tusd"
)
//go:generate mockgen -package tusd_test -source utils_test.go -aux_files tusd=datastore.go -destination=handler_mock_test.go
// FullDataStore is an interface combining most interfaces for data stores.
// This is used by mockgen(1) to generate a mocked data store used for testing
// (see https://github.com/golang/mock). The only interface excluded is
// LockerDataStore because else we would have to explicitly expect calls for
// locking in every single test which would result in more verbose code.
// Therefore it has been moved into its own type definition, the Locker.
type FullDataStore interface {
tusd.DataStore
tusd.TerminaterDataStore
tusd.ConcaterDataStore
tusd.GetReaderDataStore
tusd.FinisherDataStore
tusd.LengthDeferrerDataStore
}
type Locker interface {
tusd.LockerDataStore
}
type httpTest struct {
Name string
Method string
URL string
ReqBody io.Reader
ReqHeader map[string]string
Code int
ResBody string
ResHeader map[string]string
}
func (test *httpTest) Run(handler http.Handler, t *testing.T) *httptest.ResponseRecorder {
req, _ := http.NewRequest(test.Method, test.URL, test.ReqBody)
// Add headers
for key, value := range test.ReqHeader {
req.Header.Set(key, value)
}
req.Host = "tus.io"
w := httptest.NewRecorder()
handler.ServeHTTP(w, req)
if w.Code != test.Code {
t.Errorf("Expected %v %s as status code (got %v %s)", test.Code, http.StatusText(test.Code), w.Code, http.StatusText(w.Code))
}
for key, value := range test.ResHeader {
header := w.HeaderMap.Get(key)
if value != header {
t.Errorf("Expected '%s' as '%s' (got '%s')", value, key, header)
}
}
if test.ResBody != "" && string(w.Body.Bytes()) != test.ResBody {
t.Errorf("Expected '%s' as body (got '%s'", test.ResBody, string(w.Body.Bytes()))
}
return w
}
type readerMatcher struct {
expect string
}
// NewReaderMatcher returns a gomock.Matcher which can be used in tests for
// expecting io.Readers as arguments. It will only report an argument x as
// matching if it's an io.Reader which, if fully read, equals the string `expect`.
func NewReaderMatcher(expect string) gomock.Matcher {
return readerMatcher{
expect: expect,
}
}
func (m readerMatcher) Matches(x interface{}) bool {
input, ok := x.(io.Reader)
if !ok {
return false
}
bytes, err := ioutil.ReadAll(input)
// Handle closed pipes similar to how EOF are handled by ioutil.ReadAll,
// we handle this error as if the stream ended normally.
if err == io.ErrClosedPipe {
err = nil
}
if err != nil {
panic(err)
}
readStr := string(bytes)
return reflect.DeepEqual(m.expect, readStr)
}
func (m readerMatcher) String() string {
return fmt.Sprintf("reads to %s", m.expect)
}