aboutsummaryrefslogtreecommitdiff
path: root/types/known/anypb/any_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'types/known/anypb/any_test.go')
-rw-r--r--types/known/anypb/any_test.go184
1 files changed, 184 insertions, 0 deletions
diff --git a/types/known/anypb/any_test.go b/types/known/anypb/any_test.go
new file mode 100644
index 00000000..68e6391c
--- /dev/null
+++ b/types/known/anypb/any_test.go
@@ -0,0 +1,184 @@
+// Copyright 2020 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 anypb_test
+
+import (
+ "testing"
+
+ "github.com/google/go-cmp/cmp"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/reflect/protoreflect"
+ "google.golang.org/protobuf/testing/protocmp"
+
+ testpb "google.golang.org/protobuf/internal/testprotos/test"
+ apb "google.golang.org/protobuf/types/known/anypb"
+ epb "google.golang.org/protobuf/types/known/emptypb"
+ wpb "google.golang.org/protobuf/types/known/wrapperspb"
+)
+
+func mustMarshal(m proto.Message) []byte {
+ b, err := proto.MarshalOptions{AllowPartial: true, Deterministic: true}.Marshal(m)
+ if err != nil {
+ panic(err)
+ }
+ return b
+}
+
+func TestMessage(t *testing.T) {
+ tests := []struct {
+ inAny *apb.Any
+ inTarget proto.Message
+ wantIs bool
+ wantName protoreflect.FullName
+ }{{
+ inAny: nil,
+ inTarget: nil,
+ wantIs: false,
+ wantName: "",
+ }, {
+ inAny: new(apb.Any),
+ inTarget: nil,
+ wantIs: false,
+ wantName: "",
+ }, {
+ inAny: new(apb.Any),
+ inTarget: (*testpb.TestAllTypes)(nil),
+ wantIs: false,
+ wantName: "",
+ }, {
+ inAny: &apb.Any{TypeUrl: "foo"},
+ inTarget: (*testpb.TestAllTypes)(nil),
+ wantIs: false,
+ wantName: "foo",
+ }, {
+ inAny: &apb.Any{TypeUrl: "foo$"},
+ inTarget: (*testpb.TestAllTypes)(nil),
+ wantIs: false,
+ wantName: "",
+ }, {
+ inAny: &apb.Any{TypeUrl: "/foo"},
+ inTarget: (*testpb.TestAllTypes)(nil),
+ wantIs: false,
+ wantName: "foo",
+ }, {
+ inAny: &apb.Any{TypeUrl: "/bar/foo"},
+ inTarget: (*testpb.TestAllTypes)(nil),
+ wantIs: false,
+ wantName: "foo",
+ }, {
+ inAny: &apb.Any{TypeUrl: "google.golang.org/bar/foo"},
+ inTarget: (*testpb.TestAllTypes)(nil),
+ wantIs: false,
+ wantName: "foo",
+ }, {
+ inAny: &apb.Any{TypeUrl: "goproto.proto.test.TestAllTypes"},
+ inTarget: (*testpb.TestAllTypes)(nil),
+ wantIs: true,
+ wantName: "goproto.proto.test.TestAllTypes",
+ }, {
+ inAny: &apb.Any{TypeUrl: "goproto.proto.test.TestAllTypes$"},
+ inTarget: (*testpb.TestAllTypes)(nil),
+ wantIs: false,
+ wantName: "",
+ }, {
+ inAny: &apb.Any{TypeUrl: "/goproto.proto.test.TestAllTypes"},
+ inTarget: (*testpb.TestAllTypes)(nil),
+ wantIs: true,
+ wantName: "goproto.proto.test.TestAllTypes",
+ }, {
+ inAny: &apb.Any{TypeUrl: "google.golang.org/foo/goproto.proto.test.TestAllTypes"},
+ inTarget: (*testpb.TestAllTypes)(nil),
+ wantIs: true,
+ wantName: "goproto.proto.test.TestAllTypes",
+ }}
+
+ for _, tt := range tests {
+ gotIs := tt.inAny.MessageIs(tt.inTarget)
+ if gotIs != tt.wantIs {
+ t.Errorf("MessageIs(%v, %v) = %v, want %v", tt.inAny, tt.inTarget, gotIs, tt.wantIs)
+ }
+ gotName := tt.inAny.MessageName()
+ if gotName != tt.wantName {
+ t.Errorf("MessageName(%v) = %v, want %v", tt.inAny, gotName, tt.wantName)
+ }
+ }
+}
+
+func TestRoundtrip(t *testing.T) {
+ tests := []struct {
+ msg proto.Message
+ any *apb.Any
+ }{{
+ msg: &testpb.TestAllTypes{},
+ any: &apb.Any{
+ TypeUrl: "type.googleapis.com/goproto.proto.test.TestAllTypes",
+ },
+ }, {
+ msg: &testpb.TestAllTypes{
+ OptionalString: proto.String("hello, world!"),
+ },
+ any: &apb.Any{
+ TypeUrl: "type.googleapis.com/goproto.proto.test.TestAllTypes",
+ Value: mustMarshal(&testpb.TestAllTypes{
+ OptionalString: proto.String("hello, world!"),
+ }),
+ },
+ }, {
+ msg: &wpb.StringValue{Value: ""},
+ any: &apb.Any{
+ TypeUrl: "type.googleapis.com/google.protobuf.StringValue",
+ },
+ }, {
+ msg: wpb.String("hello, world"),
+ any: &apb.Any{
+ TypeUrl: "type.googleapis.com/google.protobuf.StringValue",
+ Value: mustMarshal(wpb.String("hello, world")),
+ },
+ }, {
+ msg: &apb.Any{
+ TypeUrl: "type.googleapis.com/google.protobuf.StringValue",
+ Value: mustMarshal(wpb.String("hello, world")),
+ },
+ any: &apb.Any{
+ TypeUrl: "type.googleapis.com/google.protobuf.Any",
+ Value: mustMarshal(&apb.Any{
+ TypeUrl: "type.googleapis.com/google.protobuf.StringValue",
+ Value: mustMarshal(wpb.String("hello, world")),
+ }),
+ },
+ }}
+
+ for _, tt := range tests {
+ // Unmarshal to the wrong message type.
+ var empty epb.Empty
+ if err := tt.any.UnmarshalTo(&empty); err == nil {
+ t.Errorf("UnmarshalTo(empty) = nil, want non-nil")
+ }
+
+ gotAny := new(apb.Any)
+ if err := gotAny.MarshalFrom(tt.msg); err != nil {
+ t.Errorf("MarshalFrom() error: %v", err)
+ }
+ if diff := cmp.Diff(tt.any, gotAny, protocmp.Transform()); diff != "" {
+ t.Errorf("MarshalFrom() output mismatch (-want +got):\n%s", diff)
+ }
+
+ gotPB := tt.msg.ProtoReflect().New().Interface()
+ if err := tt.any.UnmarshalTo(gotPB); err != nil {
+ t.Errorf("UnmarshalTo() error: %v", err)
+ }
+ if diff := cmp.Diff(tt.msg, gotPB, protocmp.Transform()); diff != "" {
+ t.Errorf("UnmarshalTo() output mismatch (-want +got):\n%s", diff)
+ }
+
+ gotPB, err := tt.any.UnmarshalNew()
+ if err != nil {
+ t.Errorf("UnmarshalNew() error: %v", err)
+ }
+ if diff := cmp.Diff(tt.msg, gotPB, protocmp.Transform()); diff != "" {
+ t.Errorf("UnmarshalNew() output mismatch (-want +got):\n%s", diff)
+ }
+ }
+}