Add godoc comments to exported symbols in pkg/httpmock

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Kynan Ware 2026-03-04 16:08:04 -07:00
parent 83bc80a1bb
commit 6b227a5599
3 changed files with 27 additions and 0 deletions

View file

@ -6,6 +6,7 @@ import (
// TODO: clean up methods in this file when there are no more callers
// StubRepoInfoResponse registers a stub for the RepositoryInfo GraphQL query.
func (r *Registry) StubRepoInfoResponse(owner, repo, branch string) {
r.Register(
GraphQL(`query RepositoryInfo\b`),
@ -22,14 +23,17 @@ func (r *Registry) StubRepoInfoResponse(owner, repo, branch string) {
`, repo, owner, branch)))
}
// StubRepoResponse registers a stub for the RepositoryNetwork GraphQL query with WRITE permission.
func (r *Registry) StubRepoResponse(owner, repo string) {
r.StubRepoResponseWithPermission(owner, repo, "WRITE")
}
// StubRepoResponseWithPermission registers a stub for the RepositoryNetwork GraphQL query with the given permission.
func (r *Registry) StubRepoResponseWithPermission(owner, repo, permission string) {
r.Register(GraphQL(`query RepositoryNetwork\b`), StringResponse(RepoNetworkStubResponse(owner, repo, "master", permission)))
}
// RepoNetworkStubResponse returns a JSON string representing a RepositoryNetwork GraphQL response.
func RepoNetworkStubResponse(owner, repo, defaultBranch, permission string) string {
return fmt.Sprintf(`
{ "data": { "repo_000": {

View file

@ -15,12 +15,14 @@ func ReplaceTripper(client *http.Client, reg *Registry) {
client.Transport = reg
}
// Registry tracks HTTP stubs and records requests for verification in tests.
type Registry struct {
mu sync.Mutex
stubs []*Stub
Requests []*http.Request
}
// Register adds a new stub with the given matcher and responder to the registry.
func (r *Registry) Register(m Matcher, resp Responder) {
r.stubs = append(r.stubs, &Stub{
Stack: string(debug.Stack()),
@ -29,6 +31,7 @@ func (r *Registry) Register(m Matcher, resp Responder) {
})
}
// Exclude registers a stub that causes the test to fail if a matching HTTP request is made.
func (r *Registry) Exclude(t *testing.T, m Matcher) {
registrationStack := string(debug.Stack())
@ -52,11 +55,13 @@ func (r *Registry) Exclude(t *testing.T, m Matcher) {
r.stubs = append(r.stubs, excludedStub)
}
// Testing is an interface for test error reporting used by Verify.
type Testing interface {
Errorf(string, ...interface{})
Helper()
}
// Verify reports an error if any registered stubs were not matched by an HTTP request.
func (r *Registry) Verify(t Testing) {
var unmatchedStubStacks []string
for _, s := range r.stubs {

View file

@ -13,9 +13,13 @@ import (
"github.com/cli/go-gh/v2/pkg/api"
)
// Matcher is a function that reports whether an HTTP request matches a stub.
type Matcher func(req *http.Request) bool
// Responder is a function that generates an HTTP response for a matched request.
type Responder func(req *http.Request) (*http.Response, error)
// Stub pairs a Matcher with a Responder and tracks whether the stub has been matched.
type Stub struct {
Stack string
matched bool
@ -24,6 +28,7 @@ type Stub struct {
exclude bool
}
// MatchAny is a Matcher that matches every HTTP request.
func MatchAny(*http.Request) bool {
return true
}
@ -41,6 +46,7 @@ func REST(method, p string) Matcher {
}
}
// GraphQL returns a Matcher that matches POST requests to the GraphQL endpoint whose query matches the given regex.
func GraphQL(q string) Matcher {
re := regexp.MustCompile(q)
@ -61,6 +67,7 @@ func GraphQL(q string) Matcher {
}
}
// GraphQLMutationMatcher returns a Matcher for GraphQL mutations whose query matches the regex and whose input satisfies cb.
func GraphQLMutationMatcher(q string, cb func(map[string]interface{}) bool) Matcher {
re := regexp.MustCompile(q)
@ -88,6 +95,7 @@ func GraphQLMutationMatcher(q string, cb func(map[string]interface{}) bool) Matc
}
}
// QueryMatcher returns a Matcher that matches REST requests by method, path, and query parameters.
func QueryMatcher(method string, path string, query url.Values) Matcher {
return func(req *http.Request) bool {
if !REST(method, path)(req) {
@ -121,18 +129,21 @@ func decodeJSONBody(req *http.Request, dest interface{}) error {
return json.Unmarshal(b, dest)
}
// StringResponse returns a Responder that replies with a 200 status and the given string body.
func StringResponse(body string) Responder {
return func(req *http.Request) (*http.Response, error) {
return httpResponse(200, req, bytes.NewBufferString(body)), nil
}
}
// BinaryResponse returns a Responder that replies with a 200 status and the given byte slice body.
func BinaryResponse(body []byte) Responder {
return func(req *http.Request) (*http.Response, error) {
return httpResponse(200, req, bytes.NewBuffer(body)), nil
}
}
// WithHost wraps a Matcher to additionally require the request host to match the given host.
func WithHost(matcher Matcher, host string) Matcher {
return func(req *http.Request) bool {
if !strings.EqualFold(req.Host, host) {
@ -142,6 +153,7 @@ func WithHost(matcher Matcher, host string) Matcher {
}
}
// WithHeader wraps a Responder to add the specified header to the response.
func WithHeader(responder Responder, header string, value string) Responder {
return func(req *http.Request) (*http.Response, error) {
resp, _ := responder(req)
@ -153,12 +165,14 @@ func WithHeader(responder Responder, header string, value string) Responder {
}
}
// StatusStringResponse returns a Responder that replies with the given status code and string body.
func StatusStringResponse(status int, body string) Responder {
return func(req *http.Request) (*http.Response, error) {
return httpResponse(status, req, bytes.NewBufferString(body)), nil
}
}
// JSONResponse returns a Responder that JSON-encodes the given value and replies with a 200 status.
func JSONResponse(body interface{}) Responder {
return func(req *http.Request) (*http.Response, error) {
b, _ := json.Marshal(body)
@ -188,6 +202,7 @@ func JSONErrorResponse(status int, err api.HTTPError) Responder {
return StatusJSONResponse(status, err)
}
// FileResponse returns a Responder that replies with the contents of the named file.
func FileResponse(filename string) Responder {
return func(req *http.Request) (*http.Response, error) {
f, err := os.Open(filename)
@ -198,6 +213,7 @@ func FileResponse(filename string) Responder {
}
}
// RESTPayload returns a Responder that decodes the JSON request body, passes it to cb, and replies with the given status and body.
func RESTPayload(responseStatus int, responseBody string, cb func(payload map[string]interface{})) Responder {
return func(req *http.Request) (*http.Response, error) {
bodyData := make(map[string]interface{})
@ -214,6 +230,7 @@ func RESTPayload(responseStatus int, responseBody string, cb func(payload map[st
}
}
// GraphQLMutation returns a Responder that decodes a GraphQL mutation's input variables, passes them to cb, and replies with body.
func GraphQLMutation(body string, cb func(map[string]interface{})) Responder {
return func(req *http.Request) (*http.Response, error) {
var bodyData struct {
@ -231,6 +248,7 @@ func GraphQLMutation(body string, cb func(map[string]interface{})) Responder {
}
}
// GraphQLQuery returns a Responder that decodes a GraphQL query and its variables, passes them to cb, and replies with body.
func GraphQLQuery(body string, cb func(string, map[string]interface{})) Responder {
return func(req *http.Request) (*http.Response, error) {
var bodyData struct {