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 118 119 120 121 122 123 124 125 126
|
// +build ignore
package main
import (
"os"
"text/template"
)
func main() {
Run(srcTemplate, testTemplate, os.Args...)
}
var srcTemplate = template.Must(template.New("").Parse(`package {{.Package}}
// go generate {{.Args}}
// GENERATED CODE FOLLOWS; DO NOT EDIT.
import (
"context"
"github.com/mesos/mesos-go/api/v1/lib"
"github.com/mesos/mesos-go/api/v1/lib/client"
"github.com/mesos/mesos-go/api/v1/lib/httpcli"
{{range .Imports}}{{/* a "calls" package is assumed to be imported */}}
{{ printf "%q" . -}}
{{end}}
)
{{.RequireType "C" -}}{{/* C is assumed to be a struct type */ -}}
{{.RequirePrototype "C" -}}
// ResponseClassifier determines the appropriate response class for the given call.
type ResponseClassifier func(*{{.Type "C"}}) (client.ResponseClass, error)
// ClientFunc sends a Request to Mesos and returns the generated Response.
type ClientFunc func(client.Request, client.ResponseClass, ...httpcli.RequestOpt) (mesos.Response, error)
{{/* classifyResponse must be declared in the package wherein this generated module lives */ -}}
// DefaultResponseClassifier is a pluggable classifier.
var DefaultResponseClassifier = ResponseClassifier(classifyResponse)
// NewSender generates a sender that uses the Mesos v1 HTTP API for encoding/decoding requests/responses.
// The ResponseClass is inferred from the first object generated by the given Request.
func NewSender(cf ClientFunc, ro ...httpcli.RequestOpt) calls.Sender {
return calls.SenderFunc(func(ctx context.Context, r calls.Request) (mesos.Response, error) {
var (
obj = r.Call()
rc, err = DefaultResponseClassifier(obj)
)
if err != nil {
return nil, err
}
var req client.Request
switch r := r.(type) {
case calls.RequestStreaming:
req = calls.Push(r, obj)
default:
req = calls.NonStreaming(obj)
}
return cf(req, rc, append(ro, httpcli.Context(ctx))...)
})
}
`))
var testTemplate = template.Must(template.New("").Parse(`package {{.Package}}
// go generate {{.Args}}
// GENERATED CODE FOLLOWS; DO NOT EDIT.
import (
"context"
"testing"
"github.com/mesos/mesos-go/api/v1/lib"
"github.com/mesos/mesos-go/api/v1/lib/client"
"github.com/mesos/mesos-go/api/v1/lib/httpcli"
{{range .Imports}}{{/* a "calls" package is assumed to be imported */}}
{{ printf "%q" . -}}
{{end}}
)
func TestNewSender(t *testing.T) {
ch := make(chan client.Request, 1)
cf := ClientFunc(func(r client.Request, _ client.ResponseClass, _ ...httpcli.RequestOpt) (_ mesos.Response, _ error) {
ch <- r
return
})
check := func(_ mesos.Response, err error) {
if err != nil {
t.Fatal(err)
}
}
sent := func() client.Request {
select {
case r := <-ch:
return r
default:
t.Fatal("no request was sent")
}
return nil
}
sender := NewSender(cf)
c := &{{.Prototype "C"}}
check(sender.Send(context.Background(), calls.NonStreaming(c)))
r := sent()
if _, ok := r.(client.RequestStreaming); ok {
t.Fatalf("expected non-streaming request instead of %v", r)
}
check(sender.Send(context.Background(), calls.Empty().Push(c)))
r = sent()
if _, ok := r.(client.RequestStreaming); !ok {
t.Fatalf("expected streaming request instead of %v", r)
}
// expect this to fail because newly created call structs don't have a type
// that can be used for classifying an expected response type.
_, err := sender.Send(context.Background(), calls.Empty().Push(new({{.Type "C"}})))
if err == nil {
t.Fatal("expected send to fail w/ malformed call")
}
}
`))
|