trpc.group/trpc-go/trpc-cmdline@v1.0.9/util/apidocs/swagger_test.go (about) 1 // Tencent is pleased to support the open source community by making tRPC available. 2 // 3 // Copyright (C) 2023 THL A29 Limited, a Tencent company. 4 // All rights reserved. 5 // 6 // If you have downloaded a copy of the tRPC source code from Tencent, 7 // please note that tRPC source code is licensed under the Apache 2.0 License, 8 // A copy of the Apache 2.0 License is included in this file. 9 10 package apidocs 11 12 import ( 13 "encoding/json" 14 "fmt" 15 "os" 16 17 "reflect" 18 "testing" 19 20 "github.com/agiledragon/gomonkey" 21 "github.com/jhump/protoreflect/desc" 22 "github.com/stretchr/testify/require" 23 24 "trpc.group/trpc-go/trpc-cmdline/descriptor" 25 "trpc.group/trpc-go/trpc-cmdline/params" 26 "trpc.group/trpc-go/trpc-cmdline/parser" 27 "trpc.group/trpc-go/trpc-cmdline/util/paths" 28 ) 29 30 func TestNewSwagger(t *testing.T) { 31 type args struct { 32 fd *descriptor.FileDescriptor 33 option *params.Option 34 } 35 tests := []struct { 36 name string 37 args args 38 want *SwaggerJSON 39 wantErr bool 40 genSwaggerInfoErr error 41 }{ 42 { 43 name: "case1-genSwaggerInfo_error", 44 args: args{ 45 fd: &descriptor.FileDescriptor{ 46 FD: &descriptor.ProtoFileDescriptor{ 47 FD: &desc.FileDescriptor{}, 48 }, 49 }, 50 option: ¶ms.Option{}, 51 }, 52 want: nil, 53 wantErr: true, 54 genSwaggerInfoErr: fmt.Errorf("error"), 55 }, 56 { 57 name: "case1-fd_nil", 58 args: args{ 59 fd: &descriptor.FileDescriptor{}, 60 option: ¶ms.Option{}, 61 }, 62 want: nil, 63 wantErr: true, 64 }, 65 { 66 name: "case2-success", 67 args: args{ 68 fd: &descriptor.FileDescriptor{ 69 FD: &descriptor.ProtoFileDescriptor{ 70 FD: &desc.FileDescriptor{}, 71 }, 72 }, 73 option: ¶ms.Option{}, 74 }, 75 want: &SwaggerJSON{ 76 Swagger: "2.0", 77 Info: InfoStruct{}, 78 Consumes: []string{"application/json"}, 79 Produces: []string{"application/json"}, 80 Paths: Paths{ 81 Elements: make(map[string]Methods), 82 Rank: make(map[string]int), 83 }, 84 Definitions: make(map[string]ModelStruct), 85 }, 86 wantErr: false, 87 }, 88 } 89 for _, tt := range tests { 90 t.Run(tt.name, func(t *testing.T) { 91 p := gomonkey.ApplyFunc( 92 NewInfo, 93 func(fd *descriptor.FileDescriptor) (InfoStruct, error) { 94 return InfoStruct{}, tt.genSwaggerInfoErr 95 }, 96 ) 97 98 p.ApplyFunc( 99 NewDefinitions, 100 func(options *params.Option, fds ...descriptor.Desc) *Definitions { 101 return &Definitions{ 102 models: make(map[string]ModelStruct), 103 } 104 }, 105 ) 106 107 p.ApplyFunc( 108 NewPaths, 109 func(fd *descriptor.FileDescriptor, option *params.Option, defs *Definitions) (Paths, error) { 110 return Paths{ 111 Elements: make(map[string]Methods), 112 Rank: make(map[string]int), 113 }, nil 114 }, 115 ) 116 117 defer p.Reset() 118 119 got, err := NewSwagger(tt.args.fd, tt.args.option) 120 if (err != nil) != tt.wantErr { 121 t.Errorf("NewSwagger() error = %v, wantErr %v", err, tt.wantErr) 122 return 123 } 124 if !reflect.DeepEqual(got, tt.want) { 125 t.Errorf("NewSwagger() got = %v, want %v", got, tt.want) 126 } 127 }) 128 } 129 } 130 131 func TestNewSwagger_with_file(t *testing.T) { 132 option := ¶ms.Option{ 133 Protodirs: append([]string{ 134 ".", 135 "../../install", 136 "../../install/protos", 137 }, paths.ExpandTRPCSearch("../../install")...), 138 Protofile: "testcase/hello.proto", 139 ProtofileAbs: "testcase/hello.proto", 140 SwaggerOptJSONParam: true, 141 KeepOrigRPCName: true, 142 } 143 144 fd, err := parser.ParseProtoFile( 145 option.Protofile, 146 option.Protodirs, 147 parser.WithAliasOn(option.AliasOn), 148 parser.WithLanguage(option.Language), 149 parser.WithRPCOnly(option.RPCOnly), 150 ) 151 if err != nil { 152 t.Logf("cannot parse proto file, option: %+v, err: %+v", option, err) 153 t.FailNow() 154 } 155 156 swagger, err := NewSwagger(fd, option) 157 require.NoError(t, err) 158 159 gotByte, err := json.MarshalIndent(swagger, "", " ") 160 require.NoError(t, err) 161 162 wantByte, err := os.ReadFile("testcase/swagger.json") 163 require.NoError(t, err) 164 165 require.Equal(t, string(wantByte), string(gotByte)) 166 } 167 168 func TestNewSwagger_OrderByPBName_with_file(t *testing.T) { 169 option := ¶ms.Option{ 170 Protodirs: append([]string{ 171 ".", 172 "../../install", 173 "../../install/protos", 174 }, paths.ExpandTRPCSearch("../../install")...), 175 Protofile: "testcase/hello.proto", 176 ProtofileAbs: "testcase/hello.proto", 177 SwaggerOptJSONParam: true, 178 OrderByPBName: true, 179 KeepOrigRPCName: true, 180 } 181 182 fd, err := parser.ParseProtoFile( 183 option.Protofile, 184 option.Protodirs, 185 parser.WithAliasOn(option.AliasOn), 186 parser.WithLanguage(option.Language), 187 parser.WithRPCOnly(option.RPCOnly), 188 ) 189 if err != nil { 190 t.Logf("cannot parse proto file, option: %+v, err: %+v", option, err) 191 t.FailNow() 192 } 193 194 swagger, err := NewSwagger(fd, option) 195 require.NoError(t, err) 196 197 gotByte, err := json.MarshalIndent(swagger, "", " ") 198 require.NoError(t, err) 199 200 wantByte, err := os.ReadFile("testcase/swagger_order_by_pbname.json") 201 require.NoError(t, err) 202 203 require.Equal(t, string(wantByte), string(gotByte)) 204 } 205 206 func TestNewSwagger_Unmarshal_file(t *testing.T) { 207 option := ¶ms.Option{ 208 Protodirs: append([]string{ 209 ".", 210 "../../install", 211 "../../install/protos", 212 }, paths.ExpandTRPCSearch("../../install")...), 213 Protofile: "testcase/hello.proto", 214 ProtofileAbs: "testcase/hello.proto", 215 SwaggerOptJSONParam: true, 216 OrderByPBName: true, 217 KeepOrigRPCName: true, 218 } 219 220 fd, err := parser.ParseProtoFile( 221 option.Protofile, 222 option.Protodirs, 223 parser.WithAliasOn(option.AliasOn), 224 parser.WithLanguage(option.Language), 225 parser.WithRPCOnly(option.RPCOnly), 226 ) 227 if err != nil { 228 t.Logf("cannot parse proto file, option: %+v, err: %+v", option, err) 229 t.FailNow() 230 } 231 232 gotSwagger, err := NewSwagger(fd, option) 233 require.NoError(t, err) 234 235 wantByte, err := os.ReadFile("testcase/swagger_order_by_pbname.json") 236 require.NoError(t, err) 237 238 var wantSwagger = &SwaggerJSON{} 239 err = json.Unmarshal(wantByte, wantSwagger) 240 require.NoError(t, err) 241 242 require.Equal(t, wantSwagger, gotSwagger) 243 }