Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set no global variables #114

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 40 additions & 88 deletions gock.go
Original file line number Diff line number Diff line change
@@ -1,57 +1,43 @@
package gock

import (
"fmt"
"net/http"
"net/http/httputil"
"net/url"
"regexp"
"sync"

"github.com/h2non/gock/threadsafe"
)

var g = threadsafe.NewGock()

func init() {
g.DisableCallback = disable
g.InterceptCallback = intercept
g.InterceptingCallback = intercepting
}

// mutex is used interally for locking thread-sensitive functions.
var mutex = &sync.Mutex{}

// config global singleton store.
var config = struct {
Networking bool
NetworkingFilters []FilterRequestFunc
Observer ObserverFunc
}{}

// ObserverFunc is implemented by users to inspect the outgoing intercepted HTTP traffic
type ObserverFunc func(*http.Request, Mock)
type ObserverFunc = threadsafe.ObserverFunc

// DumpRequest is a default implementation of ObserverFunc that dumps
// the HTTP/1.x wire representation of the http request
var DumpRequest ObserverFunc = func(request *http.Request, mock Mock) {
bytes, _ := httputil.DumpRequestOut(request, true)
fmt.Println(string(bytes))
fmt.Printf("\nMatches: %v\n---\n", mock != nil)
}

// track unmatched requests so they can be tested for
var unmatchedRequests = []*http.Request{}
var DumpRequest = g.DumpRequest

// New creates and registers a new HTTP mock with
// default settings and returns the Request DSL for HTTP mock
// definition and set up.
func New(uri string) *Request {
Intercept()

res := NewResponse()
req := NewRequest()
req.URLStruct, res.Error = url.Parse(normalizeURI(uri))

// Create the new mock expectation
exp := NewMock(req, res)
Register(exp)

return req
return g.New(uri)
}

// Intercepting returns true if gock is currently able to intercept.
func Intercepting() bool {
return g.Intercepting()
}

func intercepting() bool {
mutex.Lock()
defer mutex.Unlock()
return http.DefaultTransport == DefaultTransport
Expand All @@ -60,37 +46,33 @@ func Intercepting() bool {
// Intercept enables HTTP traffic interception via http.DefaultTransport.
// If you are using a custom HTTP transport, you have to use `gock.Transport()`
func Intercept() {
if !Intercepting() {
mutex.Lock()
http.DefaultTransport = DefaultTransport
mutex.Unlock()
}
g.Intercept()
}

func intercept() {
mutex.Lock()
http.DefaultTransport = DefaultTransport
mutex.Unlock()
}

// InterceptClient allows the developer to intercept HTTP traffic using
// a custom http.Client who uses a non default http.Transport/http.RoundTripper implementation.
func InterceptClient(cli *http.Client) {
_, ok := cli.Transport.(*Transport)
if ok {
return // if transport already intercepted, just ignore it
}
trans := NewTransport()
trans.Transport = cli.Transport
cli.Transport = trans
g.InterceptClient(cli)
}

// RestoreClient allows the developer to disable and restore the
// original transport in the given http.Client.
func RestoreClient(cli *http.Client) {
trans, ok := cli.Transport.(*Transport)
if !ok {
return
}
cli.Transport = trans.Transport
g.RestoreClient(cli)
}

// Disable disables HTTP traffic interception by gock.
func Disable() {
g.Disable()
}

func disable() {
mutex.Lock()
defer mutex.Unlock()
http.DefaultTransport = NativeTransport
Expand All @@ -99,80 +81,50 @@ func Disable() {
// Off disables the default HTTP interceptors and removes
// all the registered mocks, even if they has not been intercepted yet.
func Off() {
Flush()
Disable()
g.Off()
}

// OffAll is like `Off()`, but it also removes the unmatched requests registry.
func OffAll() {
Flush()
Disable()
CleanUnmatchedRequest()
g.OffAll()
}

// Observe provides a hook to support inspection of the request and matched mock
func Observe(fn ObserverFunc) {
mutex.Lock()
defer mutex.Unlock()
config.Observer = fn
g.Observe(fn)
}

// EnableNetworking enables real HTTP networking
func EnableNetworking() {
mutex.Lock()
defer mutex.Unlock()
config.Networking = true
g.EnableNetworking()
}

// DisableNetworking disables real HTTP networking
func DisableNetworking() {
mutex.Lock()
defer mutex.Unlock()
config.Networking = false
g.DisableNetworking()
}

// NetworkingFilter determines if an http.Request should be triggered or not.
func NetworkingFilter(fn FilterRequestFunc) {
mutex.Lock()
defer mutex.Unlock()
config.NetworkingFilters = append(config.NetworkingFilters, fn)
g.NetworkingFilter(fn)
}

// DisableNetworkingFilters disables registered networking filters.
func DisableNetworkingFilters() {
mutex.Lock()
defer mutex.Unlock()
config.NetworkingFilters = []FilterRequestFunc{}
g.DisableNetworkingFilters()
}

// GetUnmatchedRequests returns all requests that have been received but haven't matched any mock
func GetUnmatchedRequests() []*http.Request {
mutex.Lock()
defer mutex.Unlock()
return unmatchedRequests
return g.GetUnmatchedRequests()
}

// HasUnmatchedRequest returns true if gock has received any requests that didn't match a mock
func HasUnmatchedRequest() bool {
return len(GetUnmatchedRequests()) > 0
return g.HasUnmatchedRequest()
}

// CleanUnmatchedRequest cleans the unmatched requests internal registry.
func CleanUnmatchedRequest() {
mutex.Lock()
defer mutex.Unlock()
unmatchedRequests = []*http.Request{}
}

func trackUnmatchedRequest(req *http.Request) {
mutex.Lock()
defer mutex.Unlock()
unmatchedRequests = append(unmatchedRequests, req)
}

func normalizeURI(uri string) string {
if ok, _ := regexp.MatchString("^http[s]?", uri); !ok {
return "http://" + uri
}
return uri
g.CleanUnmatchedRequest()
}
2 changes: 1 addition & 1 deletion gock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ func TestUnmatched(t *testing.T) {
defer after()

// clear out any unmatchedRequests from other tests
unmatchedRequests = []*http.Request{}
CleanUnmatchedRequest()

Intercept()

Expand Down
Loading