reg/vendor/github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/genswagger/template_test.go
Jess Frazelle 843aebf2c1
update deps
Signed-off-by: Jess Frazelle <acidburn@microsoft.com>
2018-07-14 11:48:41 -04:00

890 lines
26 KiB
Go

package genswagger
import (
"reflect"
"testing"
"github.com/golang/protobuf/proto"
protodescriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
"github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
"github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/httprule"
"fmt"
)
func crossLinkFixture(f *descriptor.File) *descriptor.File {
for _, m := range f.Messages {
m.File = f
}
for _, svc := range f.Services {
svc.File = f
for _, m := range svc.Methods {
m.Service = svc
for _, b := range m.Bindings {
b.Method = m
for _, param := range b.PathParams {
param.Method = m
}
}
}
}
return f
}
func TestMessageToQueryParameters(t *testing.T) {
type test struct {
MsgDescs []*protodescriptor.DescriptorProto
Message string
Params []swaggerParameterObject
}
tests := []test{
{
MsgDescs: []*protodescriptor.DescriptorProto{
&protodescriptor.DescriptorProto{
Name: proto.String("ExampleMessage"),
Field: []*protodescriptor.FieldDescriptorProto{
{
Name: proto.String("a"),
Type: protodescriptor.FieldDescriptorProto_TYPE_STRING.Enum(),
Number: proto.Int32(1),
},
{
Name: proto.String("b"),
Type: protodescriptor.FieldDescriptorProto_TYPE_DOUBLE.Enum(),
Number: proto.Int32(2),
},
},
},
},
Message: "ExampleMessage",
Params: []swaggerParameterObject{
swaggerParameterObject{
Name: "a",
In: "query",
Required: false,
Type: "string",
},
swaggerParameterObject{
Name: "b",
In: "query",
Required: false,
Type: "number",
Format: "double",
},
},
},
{
MsgDescs: []*protodescriptor.DescriptorProto{
&protodescriptor.DescriptorProto{
Name: proto.String("ExampleMessage"),
Field: []*protodescriptor.FieldDescriptorProto{
{
Name: proto.String("nested"),
Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
TypeName: proto.String(".example.Nested"),
Number: proto.Int32(1),
},
},
},
&protodescriptor.DescriptorProto{
Name: proto.String("Nested"),
Field: []*protodescriptor.FieldDescriptorProto{
{
Name: proto.String("a"),
Type: protodescriptor.FieldDescriptorProto_TYPE_STRING.Enum(),
Number: proto.Int32(1),
},
{
Name: proto.String("deep"),
Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
TypeName: proto.String(".example.Nested.DeepNested"),
Number: proto.Int32(2),
},
},
NestedType: []*protodescriptor.DescriptorProto{{
Name: proto.String("DeepNested"),
Field: []*protodescriptor.FieldDescriptorProto{
{
Name: proto.String("b"),
Type: protodescriptor.FieldDescriptorProto_TYPE_STRING.Enum(),
Number: proto.Int32(1),
},
{
Name: proto.String("c"),
Type: protodescriptor.FieldDescriptorProto_TYPE_ENUM.Enum(),
TypeName: proto.String(".example.Nested.DeepNested.DeepEnum"),
Number: proto.Int32(2),
},
},
EnumType: []*protodescriptor.EnumDescriptorProto{
{
Name: proto.String("DeepEnum"),
Value: []*protodescriptor.EnumValueDescriptorProto{
{Name: proto.String("FALSE"), Number: proto.Int32(0)},
{Name: proto.String("TRUE"), Number: proto.Int32(1)},
},
},
},
}},
},
},
Message: "ExampleMessage",
Params: []swaggerParameterObject{
swaggerParameterObject{
Name: "nested.a",
In: "query",
Required: false,
Type: "string",
},
swaggerParameterObject{
Name: "nested.deep.b",
In: "query",
Required: false,
Type: "string",
},
swaggerParameterObject{
Name: "nested.deep.c",
In: "query",
Required: false,
Type: "string",
Enum: []string{"FALSE", "TRUE"},
Default: "FALSE",
},
},
},
}
for _, test := range tests {
reg := descriptor.NewRegistry()
msgs := []*descriptor.Message{}
for _, msgdesc := range test.MsgDescs {
msgs = append(msgs, &descriptor.Message{DescriptorProto: msgdesc})
}
file := descriptor.File{
FileDescriptorProto: &protodescriptor.FileDescriptorProto{
SourceCodeInfo: &protodescriptor.SourceCodeInfo{},
Name: proto.String("example.proto"),
Package: proto.String("example"),
Dependency: []string{},
MessageType: test.MsgDescs,
Service: []*protodescriptor.ServiceDescriptorProto{},
},
GoPkg: descriptor.GoPackage{
Path: "example.com/path/to/example/example.pb",
Name: "example_pb",
},
Messages: msgs,
}
reg.Load(&plugin.CodeGeneratorRequest{
ProtoFile: []*protodescriptor.FileDescriptorProto{file.FileDescriptorProto},
})
message, err := reg.LookupMsg("", ".example."+test.Message)
if err != nil {
t.Fatalf("failed to lookup message: %s", err)
}
params, err := messageToQueryParameters(message, reg, []descriptor.Parameter{})
if err != nil {
t.Fatalf("failed to convert message to query parameters: %s", err)
}
if !reflect.DeepEqual(params, test.Params) {
t.Errorf("expected %v, got %v", test.Params, params)
}
}
}
func TestApplyTemplateSimple(t *testing.T) {
msgdesc := &protodescriptor.DescriptorProto{
Name: proto.String("ExampleMessage"),
}
meth := &protodescriptor.MethodDescriptorProto{
Name: proto.String("Example"),
InputType: proto.String("ExampleMessage"),
OutputType: proto.String("ExampleMessage"),
}
svc := &protodescriptor.ServiceDescriptorProto{
Name: proto.String("ExampleService"),
Method: []*protodescriptor.MethodDescriptorProto{meth},
}
msg := &descriptor.Message{
DescriptorProto: msgdesc,
}
file := descriptor.File{
FileDescriptorProto: &protodescriptor.FileDescriptorProto{
SourceCodeInfo: &protodescriptor.SourceCodeInfo{},
Name: proto.String("example.proto"),
Package: proto.String("example"),
Dependency: []string{"a.example/b/c.proto", "a.example/d/e.proto"},
MessageType: []*protodescriptor.DescriptorProto{msgdesc},
Service: []*protodescriptor.ServiceDescriptorProto{svc},
},
GoPkg: descriptor.GoPackage{
Path: "example.com/path/to/example/example.pb",
Name: "example_pb",
},
Messages: []*descriptor.Message{msg},
Services: []*descriptor.Service{
{
ServiceDescriptorProto: svc,
Methods: []*descriptor.Method{
{
MethodDescriptorProto: meth,
RequestType: msg,
ResponseType: msg,
Bindings: []*descriptor.Binding{
{
HTTPMethod: "GET",
Body: &descriptor.Body{FieldPath: nil},
PathTmpl: httprule.Template{
Version: 1,
OpCodes: []int{0, 0},
Template: "/v1/echo", // TODO(achew22): Figure out what this should really be
},
},
},
},
},
},
},
}
result, err := applyTemplate(param{File: crossLinkFixture(&file), reg: descriptor.NewRegistry()})
if err != nil {
t.Errorf("applyTemplate(%#v) failed with %v; want success", file, err)
return
}
if want, is, name := "2.0", result.Swagger, "Swagger"; !reflect.DeepEqual(is, want) {
t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
}
if want, is, name := "", result.BasePath, "BasePath"; !reflect.DeepEqual(is, want) {
t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
}
if want, is, name := []string{"http", "https"}, result.Schemes, "Schemes"; !reflect.DeepEqual(is, want) {
t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
}
if want, is, name := []string{"application/json"}, result.Consumes, "Consumes"; !reflect.DeepEqual(is, want) {
t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
}
if want, is, name := []string{"application/json"}, result.Produces, "Produces"; !reflect.DeepEqual(is, want) {
t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, is, want)
}
// If there was a failure, print out the input and the json result for debugging.
if t.Failed() {
t.Errorf("had: %s", file)
t.Errorf("got: %s", fmt.Sprint(result))
}
}
func TestApplyTemplateRequestWithoutClientStreaming(t *testing.T) {
t.Skip()
msgdesc := &protodescriptor.DescriptorProto{
Name: proto.String("ExampleMessage"),
Field: []*protodescriptor.FieldDescriptorProto{
{
Name: proto.String("nested"),
Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
TypeName: proto.String("NestedMessage"),
Number: proto.Int32(1),
},
},
}
nesteddesc := &protodescriptor.DescriptorProto{
Name: proto.String("NestedMessage"),
Field: []*protodescriptor.FieldDescriptorProto{
{
Name: proto.String("int32"),
Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
Type: protodescriptor.FieldDescriptorProto_TYPE_INT32.Enum(),
Number: proto.Int32(1),
},
{
Name: proto.String("bool"),
Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
Type: protodescriptor.FieldDescriptorProto_TYPE_BOOL.Enum(),
Number: proto.Int32(2),
},
},
}
meth := &protodescriptor.MethodDescriptorProto{
Name: proto.String("Echo"),
InputType: proto.String("ExampleMessage"),
OutputType: proto.String("ExampleMessage"),
ClientStreaming: proto.Bool(false),
}
svc := &protodescriptor.ServiceDescriptorProto{
Name: proto.String("ExampleService"),
Method: []*protodescriptor.MethodDescriptorProto{meth},
}
meth.ServerStreaming = proto.Bool(false)
msg := &descriptor.Message{
DescriptorProto: msgdesc,
}
nested := &descriptor.Message{
DescriptorProto: nesteddesc,
}
nestedField := &descriptor.Field{
Message: msg,
FieldDescriptorProto: msg.GetField()[0],
}
intField := &descriptor.Field{
Message: nested,
FieldDescriptorProto: nested.GetField()[0],
}
boolField := &descriptor.Field{
Message: nested,
FieldDescriptorProto: nested.GetField()[1],
}
file := descriptor.File{
FileDescriptorProto: &protodescriptor.FileDescriptorProto{
SourceCodeInfo: &protodescriptor.SourceCodeInfo{},
Name: proto.String("example.proto"),
Package: proto.String("example"),
MessageType: []*protodescriptor.DescriptorProto{msgdesc, nesteddesc},
Service: []*protodescriptor.ServiceDescriptorProto{svc},
},
GoPkg: descriptor.GoPackage{
Path: "example.com/path/to/example/example.pb",
Name: "example_pb",
},
Messages: []*descriptor.Message{msg, nested},
Services: []*descriptor.Service{
{
ServiceDescriptorProto: svc,
Methods: []*descriptor.Method{
{
MethodDescriptorProto: meth,
RequestType: msg,
ResponseType: msg,
Bindings: []*descriptor.Binding{
{
HTTPMethod: "POST",
PathTmpl: httprule.Template{
Version: 1,
OpCodes: []int{0, 0},
Template: "/v1/echo", // TODO(achew): Figure out what this hsould really be
},
PathParams: []descriptor.Parameter{
{
FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{
{
Name: "nested",
Target: nestedField,
},
{
Name: "int32",
Target: intField,
},
}),
Target: intField,
},
},
Body: &descriptor.Body{
FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{
{
Name: "nested",
Target: nestedField,
},
{
Name: "bool",
Target: boolField,
},
}),
},
},
},
},
},
},
},
}
result, err := applyTemplate(param{File: crossLinkFixture(&file)})
if err != nil {
t.Errorf("applyTemplate(%#v) failed with %v; want success", file, err)
return
}
if want, got := "2.0", result.Swagger; !reflect.DeepEqual(got, want) {
t.Errorf("applyTemplate(%#v).Swagger = %s want to be %s", file, got, want)
}
if want, got := "", result.BasePath; !reflect.DeepEqual(got, want) {
t.Errorf("applyTemplate(%#v).BasePath = %s want to be %s", file, got, want)
}
if want, got := []string{"http", "https"}, result.Schemes; !reflect.DeepEqual(got, want) {
t.Errorf("applyTemplate(%#v).Schemes = %s want to be %s", file, got, want)
}
if want, got := []string{"application/json"}, result.Consumes; !reflect.DeepEqual(got, want) {
t.Errorf("applyTemplate(%#v).Consumes = %s want to be %s", file, got, want)
}
if want, got := []string{"application/json"}, result.Produces; !reflect.DeepEqual(got, want) {
t.Errorf("applyTemplate(%#v).Produces = %s want to be %s", file, got, want)
}
if want, got, name := "Generated for ExampleService.Echo - ", result.Paths["/v1/echo"].Post.Summary, "Paths[/v1/echo].Post.Summary"; !reflect.DeepEqual(got, want) {
t.Errorf("applyTemplate(%#v).%s = %s want to be %s", file, name, got, want)
}
// If there was a failure, print out the input and the json result for debugging.
if t.Failed() {
t.Errorf("had: %s", file)
t.Errorf("got: %s", fmt.Sprint(result))
}
}
func TestApplyTemplateRequestWithClientStreaming(t *testing.T) {
t.Skip()
msgdesc := &protodescriptor.DescriptorProto{
Name: proto.String("ExampleMessage"),
Field: []*protodescriptor.FieldDescriptorProto{
{
Name: proto.String("nested"),
Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
TypeName: proto.String("NestedMessage"),
Number: proto.Int32(1),
},
},
}
nesteddesc := &protodescriptor.DescriptorProto{
Name: proto.String("NestedMessage"),
Field: []*protodescriptor.FieldDescriptorProto{
{
Name: proto.String("int32"),
Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
Type: protodescriptor.FieldDescriptorProto_TYPE_INT32.Enum(),
Number: proto.Int32(1),
},
{
Name: proto.String("bool"),
Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
Type: protodescriptor.FieldDescriptorProto_TYPE_BOOL.Enum(),
Number: proto.Int32(2),
},
},
}
meth := &protodescriptor.MethodDescriptorProto{
Name: proto.String("Echo"),
InputType: proto.String("ExampleMessage"),
OutputType: proto.String("ExampleMessage"),
ClientStreaming: proto.Bool(true),
ServerStreaming: proto.Bool(true),
}
svc := &protodescriptor.ServiceDescriptorProto{
Name: proto.String("ExampleService"),
Method: []*protodescriptor.MethodDescriptorProto{meth},
}
msg := &descriptor.Message{
DescriptorProto: msgdesc,
}
nested := &descriptor.Message{
DescriptorProto: nesteddesc,
}
nestedField := &descriptor.Field{
Message: msg,
FieldDescriptorProto: msg.GetField()[0],
}
intField := &descriptor.Field{
Message: nested,
FieldDescriptorProto: nested.GetField()[0],
}
boolField := &descriptor.Field{
Message: nested,
FieldDescriptorProto: nested.GetField()[1],
}
file := descriptor.File{
FileDescriptorProto: &protodescriptor.FileDescriptorProto{
SourceCodeInfo: &protodescriptor.SourceCodeInfo{},
Name: proto.String("example.proto"),
Package: proto.String("example"),
MessageType: []*protodescriptor.DescriptorProto{msgdesc, nesteddesc},
Service: []*protodescriptor.ServiceDescriptorProto{svc},
},
GoPkg: descriptor.GoPackage{
Path: "example.com/path/to/example/example.pb",
Name: "example_pb",
},
Messages: []*descriptor.Message{msg, nested},
Services: []*descriptor.Service{
{
ServiceDescriptorProto: svc,
Methods: []*descriptor.Method{
{
MethodDescriptorProto: meth,
RequestType: msg,
ResponseType: msg,
Bindings: []*descriptor.Binding{
{
HTTPMethod: "POST",
PathTmpl: httprule.Template{
Version: 1,
OpCodes: []int{0, 0},
Template: "/v1/echo", // TODO(achew): Figure out what this hsould really be
},
PathParams: []descriptor.Parameter{
{
FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{
{
Name: "nested",
Target: nestedField,
},
{
Name: "int32",
Target: intField,
},
}),
Target: intField,
},
},
Body: &descriptor.Body{
FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{
{
Name: "nested",
Target: nestedField,
},
{
Name: "bool",
Target: boolField,
},
}),
},
},
},
},
},
},
},
}
_, err := applyTemplate(param{File: crossLinkFixture(&file)})
if err == nil {
t.Errorf("applyTemplate(%#v) should have failed cause swagger doesn't support streaming", file)
return
}
}
func TestApplyTemplateRequestWithUnusedReferences(t *testing.T) {
reqdesc := &protodescriptor.DescriptorProto{
Name: proto.String("ExampleMessage"),
Field: []*protodescriptor.FieldDescriptorProto{
{
Name: proto.String("string"),
Label: protodescriptor.FieldDescriptorProto_LABEL_OPTIONAL.Enum(),
Type: protodescriptor.FieldDescriptorProto_TYPE_STRING.Enum(),
Number: proto.Int32(1),
},
},
}
respdesc := &protodescriptor.DescriptorProto{
Name: proto.String("EmptyMessage"),
}
meth := &protodescriptor.MethodDescriptorProto{
Name: proto.String("Example"),
InputType: proto.String("ExampleMessage"),
OutputType: proto.String("EmptyMessage"),
ClientStreaming: proto.Bool(false),
ServerStreaming: proto.Bool(false),
}
svc := &protodescriptor.ServiceDescriptorProto{
Name: proto.String("ExampleService"),
Method: []*protodescriptor.MethodDescriptorProto{meth},
}
req := &descriptor.Message{
DescriptorProto: reqdesc,
}
resp := &descriptor.Message{
DescriptorProto: respdesc,
}
stringField := &descriptor.Field{
Message: req,
FieldDescriptorProto: req.GetField()[0],
}
file := descriptor.File{
FileDescriptorProto: &protodescriptor.FileDescriptorProto{
SourceCodeInfo: &protodescriptor.SourceCodeInfo{},
Name: proto.String("example.proto"),
Package: proto.String("example"),
MessageType: []*protodescriptor.DescriptorProto{reqdesc, respdesc},
Service: []*protodescriptor.ServiceDescriptorProto{svc},
},
GoPkg: descriptor.GoPackage{
Path: "example.com/path/to/example/example.pb",
Name: "example_pb",
},
Messages: []*descriptor.Message{req, resp},
Services: []*descriptor.Service{
{
ServiceDescriptorProto: svc,
Methods: []*descriptor.Method{
{
MethodDescriptorProto: meth,
RequestType: req,
ResponseType: resp,
Bindings: []*descriptor.Binding{
{
HTTPMethod: "GET",
PathTmpl: httprule.Template{
Version: 1,
OpCodes: []int{0, 0},
Template: "/v1/example",
},
},
{
HTTPMethod: "POST",
PathTmpl: httprule.Template{
Version: 1,
OpCodes: []int{0, 0},
Template: "/v1/example/{string}",
},
PathParams: []descriptor.Parameter{
{
FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{
{
Name: "string",
Target: stringField,
},
}),
Target: stringField,
},
},
Body: &descriptor.Body{
FieldPath: descriptor.FieldPath([]descriptor.FieldPathComponent{
{
Name: "string",
Target: stringField,
},
}),
},
},
},
},
},
},
},
}
reg := descriptor.NewRegistry()
reg.Load(&plugin.CodeGeneratorRequest{ProtoFile: []*protodescriptor.FileDescriptorProto{file.FileDescriptorProto}})
result, err := applyTemplate(param{File: crossLinkFixture(&file), reg: reg})
if err != nil {
t.Errorf("applyTemplate(%#v) failed with %v; want success", file, err)
return
}
// Only EmptyMessage must be present, not ExampleMessage
if want, got, name := 1, len(result.Definitions), "len(Definitions)"; !reflect.DeepEqual(got, want) {
t.Errorf("applyTemplate(%#v).%s = %d want to be %d", file, name, got, want)
}
// If there was a failure, print out the input and the json result for debugging.
if t.Failed() {
t.Errorf("had: %s", file)
t.Errorf("got: %s", fmt.Sprint(result))
}
}
func TestTemplateToSwaggerPath(t *testing.T) {
var tests = []struct {
input string
expected string
}{
{"/test", "/test"},
{"/{test}", "/{test}"},
{"/{test=prefix/*}", "/{test}"},
{"/{test=prefix/that/has/multiple/parts/to/it/*}", "/{test}"},
{"/{test1}/{test2}", "/{test1}/{test2}"},
{"/{test1}/{test2}/", "/{test1}/{test2}/"},
}
for _, data := range tests {
actual := templateToSwaggerPath(data.input)
if data.expected != actual {
t.Errorf("Expected templateToSwaggerPath(%v) = %v, actual: %v", data.input, data.expected, actual)
}
}
}
func TestResolveFullyQualifiedNameToSwaggerName(t *testing.T) {
var tests = []struct {
input string
output string
listOfFQMNs []string
}{
{
".a.b.C",
"C",
[]string{
".a.b.C",
},
},
{
".a.b.C",
"abC",
[]string{
".a.C",
".a.b.C",
},
},
{
".a.b.C",
"abC",
[]string{
".C",
".a.C",
".a.b.C",
},
},
}
for _, data := range tests {
names := resolveFullyQualifiedNameToSwaggerNames(data.listOfFQMNs)
output := names[data.input]
if output != data.output {
t.Errorf("Expected fullyQualifiedNameToSwaggerName(%v) to be %s but got %s",
data.input, data.output, output)
}
}
}
func TestFQMNtoSwaggerName(t *testing.T) {
var tests = []struct {
input string
expected string
}{
{"/test", "/test"},
{"/{test}", "/{test}"},
{"/{test=prefix/*}", "/{test}"},
{"/{test=prefix/that/has/multiple/parts/to/it/*}", "/{test}"},
{"/{test1}/{test2}", "/{test1}/{test2}"},
{"/{test1}/{test2}/", "/{test1}/{test2}/"},
}
for _, data := range tests {
actual := templateToSwaggerPath(data.input)
if data.expected != actual {
t.Errorf("Expected templateToSwaggerPath(%v) = %v, actual: %v", data.input, data.expected, actual)
}
}
}
func TestSchemaOfField(t *testing.T) {
type test struct {
field *descriptor.Field
expected schemaCore
}
tests := []test{
{
field: &descriptor.Field{
FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
Name: proto.String("primitive_field"),
Type: protodescriptor.FieldDescriptorProto_TYPE_STRING.Enum(),
},
},
expected: schemaCore{
Type: "string",
},
},
{
field: &descriptor.Field{
FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
Name: proto.String("repeated_primitive_field"),
Type: protodescriptor.FieldDescriptorProto_TYPE_STRING.Enum(),
Label: protodescriptor.FieldDescriptorProto_LABEL_REPEATED.Enum(),
},
},
expected: schemaCore{
Type: "array",
Items: &swaggerItemsObject{
Type: "string",
},
},
},
{
field: &descriptor.Field{
FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
Name: proto.String("wrapped_field"),
TypeName: proto.String(".google.protobuf.StringValue"),
Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
},
},
expected: schemaCore{
Type: "string",
},
},
{
field: &descriptor.Field{
FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
Name: proto.String("repeated_wrapped_field"),
TypeName: proto.String(".google.protobuf.StringValue"),
Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
Label: protodescriptor.FieldDescriptorProto_LABEL_REPEATED.Enum(),
},
},
expected: schemaCore{
Type: "array",
Items: &swaggerItemsObject{
Type: "string",
},
},
},
{
field: &descriptor.Field{
FieldDescriptorProto: &protodescriptor.FieldDescriptorProto{
Name: proto.String("message_field"),
TypeName: proto.String(".example.Message"),
Type: protodescriptor.FieldDescriptorProto_TYPE_MESSAGE.Enum(),
},
},
expected: schemaCore{
Ref: "#/definitions/exampleMessage",
},
},
}
reg := descriptor.NewRegistry()
reg.Load(&plugin.CodeGeneratorRequest{
ProtoFile: []*protodescriptor.FileDescriptorProto{
{
SourceCodeInfo: &protodescriptor.SourceCodeInfo{},
Name: proto.String("example.proto"),
Package: proto.String("example"),
Dependency: []string{},
MessageType: []*protodescriptor.DescriptorProto{
{
Name: proto.String("Message"),
Field: []*protodescriptor.FieldDescriptorProto{
{
Name: proto.String("value"),
Type: protodescriptor.FieldDescriptorProto_TYPE_STRING.Enum(),
},
},
},
},
EnumType: []*protodescriptor.EnumDescriptorProto{
{
Name: proto.String("Message"),
},
},
Service: []*protodescriptor.ServiceDescriptorProto{},
},
},
})
for _, test := range tests {
actual := schemaOfField(test.field, reg)
if e, a := test.expected.Type, actual.Type; e != a {
t.Errorf("Expected schemaOfField(%v).Type = %s, actual: %s", test.field, e, a)
}
if e, a := test.expected.Ref, actual.Ref; e != a {
t.Errorf("Expected schemaOfField(%v).Ref = %s, actual: %s", test.field, e, a)
}
if e, a := test.expected.Items.getType(), actual.Items.getType(); e != a {
t.Errorf("Expected schemaOfField(%v).Items.Type = %v, actual.Type: %v", test.field, e, a)
}
}
}