forked from corestoreio/pkg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
http_trip.go
106 lines (94 loc) · 2.98 KB
/
http_trip.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
// Copyright 2015-present, Cyrill @ Schumacher.fm and the CoreStore contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cstesting
import (
"bytes"
"io/ioutil"
"net/http"
"os"
"sync"
"github.com/corestoreio/errors"
)
// HTTPTrip used for mocking the Transport field in http.Client.
type HTTPTrip struct {
GenerateResponse func(*http.Request) *http.Response
Err error
sync.Mutex
RequestCache map[*http.Request]struct{}
}
// NewHTTPTrip creates a new http.RoundTripper
func NewHTTPTrip(code int, body string, err error) *HTTPTrip {
return &HTTPTrip{
// use buffer pool
GenerateResponse: func(_ *http.Request) *http.Response {
return &http.Response{
StatusCode: code,
Body: ioutil.NopCloser(bytes.NewBufferString(body)),
}
},
Err: err,
RequestCache: make(map[*http.Request]struct{}),
}
}
// NewHTTPTripFromFile creates a new trip with content found in the provided file.
// You must close the body and hence close the file.
func NewHTTPTripFromFile(code int, filename string) *HTTPTrip {
fp, err := os.OpenFile(filename, os.O_RDONLY, 0)
return &HTTPTrip{
// use buffer pool
GenerateResponse: func(_ *http.Request) *http.Response {
return &http.Response{
StatusCode: code,
Body: fp,
}
},
Err: errors.NotFound.New(err, "File %q loading error", filename),
RequestCache: make(map[*http.Request]struct{}),
}
}
// RoundTrip implements http.RoundTripper and adds the Request to the
// field Req for later inspection.
func (tp *HTTPTrip) RoundTrip(r *http.Request) (*http.Response, error) {
tp.Mutex.Lock()
defer tp.Mutex.Unlock()
tp.RequestCache[r] = struct{}{}
if tp.Err != nil {
return nil, tp.Err
}
return tp.GenerateResponse(r), nil
}
// RequestsMatchAll checks if all requests in the cache matches the predicate
// function f.
func (tp *HTTPTrip) RequestsMatchAll(t interface {
Errorf(format string, args ...interface{})
}, f func(*http.Request) bool) {
tp.Mutex.Lock()
defer tp.Mutex.Unlock()
for req := range tp.RequestCache {
if !f(req) {
t.Errorf("[cstesting] Request does not match predicate f: %#v", req)
}
}
}
// RequestsCount counts the requests in the cache and compares it with your
// expected value.
func (tp *HTTPTrip) RequestsCount(t interface {
Errorf(format string, args ...interface{})
}, expected int) {
tp.Mutex.Lock()
defer tp.Mutex.Unlock()
if have, want := len(tp.RequestCache), expected; have != want {
t.Errorf("RequestsCount: Have %d vs. Want %d", have, want)
}
}