@@ -95,6 +95,7 @@ func TestGenerateConnectFile(t *testing.T) {
9595
9696 for _ , tt := range tests {
9797 t .Run (tt .name , func (t * testing.T ) {
98+ t .Parallel ()
9899 fd , err := protodesc .NewFile (tt .input , nil )
99100 if err != nil {
100101 t .Fatalf ("Failed to create FileDescriptorProto: %v" , err )
@@ -200,6 +201,7 @@ func TestGenerate(t *testing.T) {
200201
201202 for _ , tt := range tests {
202203 t .Run (tt .name , func (t * testing.T ) {
204+ t .Parallel ()
203205 resp := generate (t , tt .req )
204206 if tt .wantErr {
205207 if resp .GetError () == "" {
@@ -222,101 +224,131 @@ func TestGenerate(t *testing.T) {
222224 }
223225}
224226
225- func TestEdition2023Support (t * testing.T ) {
227+ func TestEditionSupport (t * testing.T ) {
226228 t .Parallel ()
227229
228- // Create a request with an Edition 2023 proto file
229- edition2023 := descriptorpb .Edition_EDITION_2023
230+ tests := []struct {
231+ name string
232+ edition descriptorpb.Edition
233+ protoFileName string
234+ packageName string
235+ serviceName string
236+ wantMinEdition descriptorpb.Edition
237+ wantMaxEdition descriptorpb.Edition
238+ wantGeneratedFile string
239+ wantServiceClass string
240+ }{
241+ {
242+ name : "edition 2023" ,
243+ edition : descriptorpb .Edition_EDITION_2023 ,
244+ protoFileName : "test_edition2023.proto" ,
245+ packageName : "test.edition2023" ,
246+ serviceName : "Edition2023Service" ,
247+ wantMinEdition : descriptorpb .Edition_EDITION_PROTO3 ,
248+ wantMaxEdition : descriptorpb .Edition_EDITION_2024 ,
249+ wantGeneratedFile : "test_edition2023_connect.py" ,
250+ wantServiceClass : "class Edition2023Service" ,
251+ },
252+ {
253+ name : "edition 2024" ,
254+ edition : descriptorpb .Edition_EDITION_2024 ,
255+ protoFileName : "test_edition2024.proto" ,
256+ packageName : "test.edition2024" ,
257+ serviceName : "Edition2024Service" ,
258+ wantMinEdition : descriptorpb .Edition_EDITION_PROTO3 ,
259+ wantMaxEdition : descriptorpb .Edition_EDITION_2024 ,
260+ wantGeneratedFile : "test_edition2024_connect.py" ,
261+ wantServiceClass : "class Edition2024Service" ,
262+ },
263+ }
230264
231- req := & pluginpb.CodeGeneratorRequest {
232- FileToGenerate : []string {"test_edition2023.proto" },
233- ProtoFile : []* descriptorpb.FileDescriptorProto {
234- {
235- Name : proto .String ("test_edition2023.proto" ),
236- Package : proto .String ("test.edition2023" ),
237- Edition : edition2023 .Enum (),
238- // Edition 2023 default: field_presence = EXPLICIT
239- Options : & descriptorpb.FileOptions {
240- Features : & descriptorpb.FeatureSet {
241- FieldPresence : descriptorpb .FeatureSet_EXPLICIT .Enum (),
242- },
243- },
244- Service : []* descriptorpb.ServiceDescriptorProto {
265+ for _ , tt := range tests {
266+ t .Run (tt .name , func (t * testing.T ) {
267+ t .Parallel ()
268+ req := & pluginpb.CodeGeneratorRequest {
269+ FileToGenerate : []string {tt .protoFileName },
270+ ProtoFile : []* descriptorpb.FileDescriptorProto {
245271 {
246- Name : proto .String ("Edition2023Service" ),
247- Method : [] * descriptorpb. MethodDescriptorProto {
248- {
249- Name : proto . String ( "TestMethod" ),
250- InputType : proto . String ( ".test.edition2023.TestRequest" ),
251- OutputType : proto . String ( ".test.edition2023.TestResponse" ),
272+ Name : proto .String (tt . protoFileName ),
273+ Package : proto . String ( tt . packageName ),
274+ Edition : tt . edition . Enum (),
275+ Options : & descriptorpb. FileOptions {
276+ Features : & descriptorpb. FeatureSet {
277+ FieldPresence : descriptorpb . FeatureSet_EXPLICIT . Enum ( ),
252278 },
253279 },
254- },
255- },
256- MessageType : []* descriptorpb.DescriptorProto {
257- {
258- Name : proto .String ("TestRequest" ),
259- Field : []* descriptorpb.FieldDescriptorProto {
280+ Service : []* descriptorpb.ServiceDescriptorProto {
260281 {
261- Name : proto .String ("message" ),
262- Number : proto .Int32 (1 ),
263- Label : descriptorpb .FieldDescriptorProto_LABEL_OPTIONAL .Enum (),
264- Type : descriptorpb .FieldDescriptorProto_TYPE_STRING .Enum (),
265- // In Edition 2023, field presence is controlled by features
282+ Name : proto .String (tt .serviceName ),
283+ Method : []* descriptorpb.MethodDescriptorProto {
284+ {
285+ Name : proto .String ("TestMethod" ),
286+ InputType : proto .String ("." + tt .packageName + ".TestRequest" ),
287+ OutputType : proto .String ("." + tt .packageName + ".TestResponse" ),
288+ },
289+ },
266290 },
267291 },
268- },
269- {
270- Name : proto .String ("TestResponse" ),
271- Field : []* descriptorpb.FieldDescriptorProto {
292+ MessageType : []* descriptorpb.DescriptorProto {
272293 {
273- Name : proto .String ("result" ),
274- Number : proto .Int32 (1 ),
275- Label : descriptorpb .FieldDescriptorProto_LABEL_OPTIONAL .Enum (),
276- Type : descriptorpb .FieldDescriptorProto_TYPE_STRING .Enum (),
294+ Name : proto .String ("TestRequest" ),
295+ Field : []* descriptorpb.FieldDescriptorProto {
296+ {
297+ Name : proto .String ("message" ),
298+ Number : proto .Int32 (1 ),
299+ Label : descriptorpb .FieldDescriptorProto_LABEL_OPTIONAL .Enum (),
300+ Type : descriptorpb .FieldDescriptorProto_TYPE_STRING .Enum (),
301+ },
302+ },
303+ },
304+ {
305+ Name : proto .String ("TestResponse" ),
306+ Field : []* descriptorpb.FieldDescriptorProto {
307+ {
308+ Name : proto .String ("result" ),
309+ Number : proto .Int32 (1 ),
310+ Label : descriptorpb .FieldDescriptorProto_LABEL_OPTIONAL .Enum (),
311+ Type : descriptorpb .FieldDescriptorProto_TYPE_STRING .Enum (),
312+ },
313+ },
277314 },
278315 },
279316 },
280317 },
281- },
282- },
283- }
318+ }
284319
285- // Call Generate
286- resp := generate (t , req )
320+ resp := generate (t , req )
287321
288- // Verify no error occurred
289- if resp .GetError () != "" {
290- t .Fatalf ("generate() failed for Edition 2023 proto: %v" , resp .GetError ())
291- }
322+ if resp .GetError () != "" {
323+ t .Fatalf ("generate() failed for %s proto: %v" , tt .name , resp .GetError ())
324+ }
292325
293- // Verify the generator declared Edition support
294- if resp .GetSupportedFeatures ()& uint64 (pluginpb .CodeGeneratorResponse_FEATURE_SUPPORTS_EDITIONS ) == 0 {
295- t .Error ("Generator should declare FEATURE_SUPPORTS_EDITIONS" )
296- }
326+ if resp .GetSupportedFeatures ()& uint64 (pluginpb .CodeGeneratorResponse_FEATURE_SUPPORTS_EDITIONS ) == 0 {
327+ t .Error ("Generator should declare FEATURE_SUPPORTS_EDITIONS" )
328+ }
297329
298- // Verify minimum and maximum editions are set
299- if resp .GetMinimumEdition () != int32 (descriptorpb .Edition_EDITION_PROTO3 ) {
300- t .Errorf ("Expected minimum edition PROTO3, got %v" , resp .GetMinimumEdition ())
301- }
302- if resp .GetMaximumEdition () != int32 (descriptorpb .Edition_EDITION_2023 ) {
303- t .Errorf ("Expected maximum edition 2023, got %v" , resp .GetMaximumEdition ())
304- }
330+ if resp .GetMinimumEdition () != int32 (tt .wantMinEdition ) {
331+ t .Errorf ("Expected minimum edition %v, got %v" , tt .wantMinEdition , resp .GetMinimumEdition ())
332+ }
333+ if resp .GetMaximumEdition () != int32 (tt .wantMaxEdition ) {
334+ t .Errorf ("Expected maximum edition %v, got %v" , tt .wantMaxEdition , resp .GetMaximumEdition ())
335+ }
305336
306- // Verify a file was generated
307- if len (resp .GetFile ()) == 0 {
308- t .Error ("No files generated for Edition 2023 proto" )
309- } else {
310- generatedFile := resp .GetFile ()[0 ]
311- if generatedFile .GetName () != "test_edition2023_connect.py" {
312- t .Errorf ("Expected filename test_edition2023_connect.py, got %v" , generatedFile .GetName ())
313- }
337+ if len (resp .GetFile ()) == 0 {
338+ t .Errorf ("No files generated for %s proto" , tt .name )
339+ return
340+ }
314341
315- // Verify the generated content includes the service
316- content := generatedFile .GetContent ()
317- if ! strings .Contains (content , "class Edition2023Service" ) {
318- t .Error ("Generated code missing Edition2023Service class" )
319- }
342+ generatedFile := resp .GetFile ()[0 ]
343+ if generatedFile .GetName () != tt .wantGeneratedFile {
344+ t .Errorf ("Expected filename %s, got %v" , tt .wantGeneratedFile , generatedFile .GetName ())
345+ }
346+
347+ content := generatedFile .GetContent ()
348+ if ! strings .Contains (content , tt .wantServiceClass ) {
349+ t .Errorf ("Generated code missing %s" , tt .wantServiceClass )
350+ }
351+ })
320352 }
321353}
322354
0 commit comments