1package gock
2
3import "net/http"
4
5// MatchersHeader exposes an slice of HTTP header specific mock matchers.
6var MatchersHeader = []MatchFunc{
7	MatchMethod,
8	MatchScheme,
9	MatchHost,
10	MatchPath,
11	MatchHeaders,
12	MatchQueryParams,
13}
14
15// MatchersBody exposes an slice of HTTP body specific built-in mock matchers.
16var MatchersBody = []MatchFunc{
17	MatchBody,
18}
19
20// Matchers stores all the built-in mock matchers.
21var Matchers = append(MatchersHeader, MatchersBody...)
22
23// DefaultMatcher stores the default Matcher instance used to match mocks.
24var DefaultMatcher = NewMatcher()
25
26// MatchFunc represents the required function
27// interface implemented by matchers.
28type MatchFunc func(*http.Request, *Request) (bool, error)
29
30// Matcher represents the required interface implemented by mock matchers.
31type Matcher interface {
32	// Get returns a slice of registered function matchers.
33	Get() []MatchFunc
34
35	// Add adds a new matcher function.
36	Add(MatchFunc)
37
38	// Set sets the matchers functions stack.
39	Set([]MatchFunc)
40
41	// Flush flushes the current matchers function stack.
42	Flush()
43
44	// Match matches the given http.Request with a mock Request.
45	Match(*http.Request, *Request) (bool, error)
46}
47
48// MockMatcher implements a mock matcher
49type MockMatcher struct {
50	Matchers []MatchFunc
51}
52
53// NewMatcher creates a new mock matcher
54// using the default matcher functions.
55func NewMatcher() *MockMatcher {
56	return &MockMatcher{Matchers: Matchers}
57}
58
59// NewBasicMatcher creates a new matcher with header only mock matchers.
60func NewBasicMatcher() *MockMatcher {
61	return &MockMatcher{Matchers: MatchersHeader}
62}
63
64// NewEmptyMatcher creates a new empty matcher with out default amtchers.
65func NewEmptyMatcher() *MockMatcher {
66	return &MockMatcher{Matchers: []MatchFunc{}}
67}
68
69// Get returns a slice of registered function matchers.
70func (m *MockMatcher) Get() []MatchFunc {
71	return m.Matchers
72}
73
74// Add adds a new function matcher.
75func (m *MockMatcher) Add(fn MatchFunc) {
76	m.Matchers = append(m.Matchers, fn)
77}
78
79// Set sets a new stack of matchers functions.
80func (m *MockMatcher) Set(stack []MatchFunc) {
81	m.Matchers = stack
82}
83
84// Flush flushes the current matcher
85func (m *MockMatcher) Flush() {
86	m.Matchers = []MatchFunc{}
87}
88
89// Match matches the given http.Request with a mock request
90// returning true in case that the request matches, otherwise false.
91func (m *MockMatcher) Match(req *http.Request, ereq *Request) (bool, error) {
92	for _, matcher := range m.Matchers {
93		matches, err := matcher(req, ereq)
94		if err != nil {
95			return false, err
96		}
97		if !matches {
98			return false, nil
99		}
100	}
101	return true, nil
102}
103
104// MatchMock is a helper function that matches the given http.Request
105// in the list of registered mocks, returning it if matches or error if it fails.
106func MatchMock(req *http.Request) (Mock, error) {
107	for _, mock := range GetAll() {
108		matches, err := mock.Match(req)
109		if err != nil {
110			return nil, err
111		}
112		if matches {
113			return mock, nil
114		}
115	}
116	return nil, nil
117}
118