| // Copyright 2024 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package proto_test |
| |
| import ( |
| "bytes" |
| "testing" |
| |
| testhybridpb "google.golang.org/protobuf/internal/testprotos/testeditions/testeditions_hybrid" |
| "google.golang.org/protobuf/proto" |
| ) |
| |
| func TestOneofOrDefault(t *testing.T) { |
| for _, tt := range []struct { |
| desc string |
| input func() *testhybridpb.TestAllTypes |
| }{ |
| { |
| desc: "struct literal with nil nested message", |
| input: func() *testhybridpb.TestAllTypes { |
| return &testhybridpb.TestAllTypes{ |
| OneofField: &testhybridpb.TestAllTypes_OneofNestedMessage{ |
| OneofNestedMessage: nil, |
| }, |
| } |
| }, |
| }, |
| |
| { |
| desc: "struct literal with non-nil nested message", |
| input: func() *testhybridpb.TestAllTypes { |
| return &testhybridpb.TestAllTypes{ |
| OneofField: &testhybridpb.TestAllTypes_OneofNestedMessage{ |
| OneofNestedMessage: &testhybridpb.TestAllTypes_NestedMessage{}, |
| }, |
| } |
| }, |
| }, |
| |
| { |
| desc: "opaque setter with ValueOrDefault", |
| input: func() *testhybridpb.TestAllTypes { |
| msg := &testhybridpb.TestAllTypes{} |
| msg.ClearOneofString() |
| var val *testhybridpb.TestAllTypes_NestedMessage |
| msg.SetOneofNestedMessage(proto.ValueOrDefault(val)) |
| return msg |
| }, |
| }, |
| |
| { |
| desc: "opaque builder with ValueOrDefault", |
| input: func() *testhybridpb.TestAllTypes { |
| var val *testhybridpb.TestAllTypes_NestedMessage |
| return testhybridpb.TestAllTypes_builder{ |
| OneofNestedMessage: proto.ValueOrDefault(val), |
| }.Build() |
| }, |
| }, |
| } { |
| t.Run(tt.desc, func(t *testing.T) { |
| msg := tt.input() |
| b, err := proto.Marshal(msg) |
| if err != nil { |
| t.Fatal(err) |
| } |
| want := []byte{130, 7, 0} |
| if !bytes.Equal(b, want) { |
| t.Fatalf("Marshal: got %x, want %x", b, want) |
| } |
| if !msg.HasOneofField() { |
| t.Fatalf("HasOneofField was false, want true") |
| } |
| if got, want := msg.WhichOneofField(), testhybridpb.TestAllTypes_OneofNestedMessage_case; got != want { |
| t.Fatalf("WhichOneofField: got %v, want %v", got, want) |
| } |
| if !msg.HasOneofNestedMessage() { |
| t.Fatalf("HasOneofNestedMessage was false, want true") |
| } |
| if msg.HasOneofString() { |
| t.Fatalf("HasOneofString was true, want false") |
| } |
| }) |
| } |
| } |
| |
| func TestOneofOrDefaultBytes(t *testing.T) { |
| for _, tt := range []struct { |
| desc string |
| input func() *testhybridpb.TestAllTypes |
| wantWire []byte |
| }{ |
| { |
| desc: "struct literal with nil bytes", |
| input: func() *testhybridpb.TestAllTypes { |
| return &testhybridpb.TestAllTypes{ |
| OneofField: &testhybridpb.TestAllTypes_OneofBytes{ |
| OneofBytes: nil, |
| }, |
| } |
| }, |
| }, |
| |
| { |
| desc: "struct literal with non-nil bytes", |
| input: func() *testhybridpb.TestAllTypes { |
| return &testhybridpb.TestAllTypes{ |
| OneofField: &testhybridpb.TestAllTypes_OneofBytes{ |
| OneofBytes: []byte{}, |
| }, |
| } |
| }, |
| }, |
| |
| { |
| desc: "opaque setter with ValueOrDefaultBytes", |
| input: func() *testhybridpb.TestAllTypes { |
| msg := &testhybridpb.TestAllTypes{} |
| msg.ClearOneofString() |
| var val []byte |
| msg.SetOneofBytes(proto.ValueOrDefaultBytes(val)) |
| return msg |
| }, |
| }, |
| |
| { |
| desc: "opaque setter", |
| input: func() *testhybridpb.TestAllTypes { |
| msg := &testhybridpb.TestAllTypes{} |
| msg.ClearOneofString() |
| var val []byte |
| msg.SetOneofBytes(val) |
| return msg |
| }, |
| }, |
| |
| { |
| desc: "opaque builder with ValueOrDefaultBytes", |
| input: func() *testhybridpb.TestAllTypes { |
| var val []byte |
| return testhybridpb.TestAllTypes_builder{ |
| OneofBytes: proto.ValueOrDefaultBytes(val), |
| }.Build() |
| }, |
| }, |
| } { |
| t.Run(tt.desc, func(t *testing.T) { |
| msg := tt.input() |
| b, err := proto.Marshal(msg) |
| if err != nil { |
| t.Fatal(err) |
| } |
| want := []byte{146, 7, 0} |
| if !bytes.Equal(b, want) { |
| t.Fatalf("Marshal: got %x, want %x", b, want) |
| } |
| if !msg.HasOneofField() { |
| t.Fatalf("HasOneofField was false, want true") |
| } |
| if got, want := msg.WhichOneofField(), testhybridpb.TestAllTypes_OneofBytes_case; got != want { |
| t.Fatalf("WhichOneofField: got %v, want %v", got, want) |
| } |
| if !msg.HasOneofBytes() { |
| t.Fatalf("HasOneofBytes was false, want true") |
| } |
| if msg.HasOneofString() { |
| t.Fatalf("HasOneofString was true, want false") |
| } |
| }) |
| } |
| } |