blob: 92d13341d681d6a45653d7f0153bcfc1c390eb73 [file] [log] [blame]
David Symonds8b1c6b72014-06-20 14:28:56 +10001// Go support for Protocol Buffers - Google's data interchange format
2//
3// Copyright 2014 The Go Authors. All rights reserved.
David Symonds558f13f2014-11-24 10:28:53 +11004// https://github.com/golang/protobuf
David Symonds8b1c6b72014-06-20 14:28:56 +10005//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are
8// met:
9//
10// * Redistributions of source code must retain the above copyright
11// notice, this list of conditions and the following disclaimer.
12// * Redistributions in binary form must reproduce the above
13// copyright notice, this list of conditions and the following disclaimer
14// in the documentation and/or other materials provided with the
15// distribution.
16// * Neither the name of Google Inc. nor the names of its
17// contributors may be used to endorse or promote products derived from
18// this software without specific prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32package proto_test
33
34import (
35 "testing"
36
David Symonds558f13f2014-11-24 10:28:53 +110037 "github.com/golang/protobuf/proto"
David Symondsa8de2842015-03-20 16:24:29 +110038 pb "github.com/golang/protobuf/proto/testdata"
David Symonds8b1c6b72014-06-20 14:28:56 +100039)
40
41func TestGetExtensionsWithMissingExtensions(t *testing.T) {
42 msg := &pb.MyMessage{}
43 ext1 := &pb.Ext{}
44 if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil {
45 t.Fatalf("Could not set ext1: %s", ext1)
46 }
47 exts, err := proto.GetExtensions(msg, []*proto.ExtensionDesc{
48 pb.E_Ext_More,
49 pb.E_Ext_Text,
50 })
51 if err != nil {
52 t.Fatalf("GetExtensions() failed: %s", err)
53 }
54 if exts[0] != ext1 {
55 t.Errorf("ext1 not in returned extensions: %T %v", exts[0], exts[0])
56 }
57 if exts[1] != nil {
58 t.Errorf("ext2 in returned extensions: %T %v", exts[1], exts[1])
59 }
60}
David Symondsce441e62014-11-18 13:50:03 +110061
62func TestGetExtensionStability(t *testing.T) {
63 check := func(m *pb.MyMessage) bool {
64 ext1, err := proto.GetExtension(m, pb.E_Ext_More)
65 if err != nil {
66 t.Fatalf("GetExtension() failed: %s", err)
67 }
68 ext2, err := proto.GetExtension(m, pb.E_Ext_More)
69 if err != nil {
70 t.Fatalf("GetExtension() failed: %s", err)
71 }
72 return ext1 == ext2
73 }
74 msg := &pb.MyMessage{Count: proto.Int32(4)}
75 ext0 := &pb.Ext{}
76 if err := proto.SetExtension(msg, pb.E_Ext_More, ext0); err != nil {
77 t.Fatalf("Could not set ext1: %s", ext0)
78 }
79 if !check(msg) {
80 t.Errorf("GetExtension() not stable before marshaling")
81 }
82 bb, err := proto.Marshal(msg)
83 if err != nil {
84 t.Fatalf("Marshal() failed: %s", err)
85 }
86 msg1 := &pb.MyMessage{}
87 err = proto.Unmarshal(bb, msg1)
88 if err != nil {
89 t.Fatalf("Unmarshal() failed: %s", err)
90 }
91 if !check(msg1) {
92 t.Errorf("GetExtension() not stable after unmarshaling")
93 }
94}
David Symonds904b4402014-12-11 08:44:00 -050095
96func TestExtensionsRoundTrip(t *testing.T) {
97 msg := &pb.MyMessage{}
98 ext1 := &pb.Ext{
99 Data: proto.String("hi"),
100 }
101 ext2 := &pb.Ext{
102 Data: proto.String("there"),
103 }
104 exists := proto.HasExtension(msg, pb.E_Ext_More)
105 if exists {
106 t.Error("Extension More present unexpectedly")
107 }
108 if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil {
109 t.Error(err)
110 }
111 if err := proto.SetExtension(msg, pb.E_Ext_More, ext2); err != nil {
112 t.Error(err)
113 }
114 e, err := proto.GetExtension(msg, pb.E_Ext_More)
115 if err != nil {
116 t.Error(err)
117 }
118 x, ok := e.(*pb.Ext)
119 if !ok {
120 t.Errorf("e has type %T, expected testdata.Ext", e)
121 } else if *x.Data != "there" {
122 t.Errorf("SetExtension failed to overwrite, got %+v, not 'there'", x)
123 }
124 proto.ClearExtension(msg, pb.E_Ext_More)
125 if _, err = proto.GetExtension(msg, pb.E_Ext_More); err != proto.ErrMissingExtension {
126 t.Errorf("got %v, expected ErrMissingExtension", e)
127 }
128 if _, err := proto.GetExtension(msg, pb.E_X215); err == nil {
129 t.Error("expected bad extension error, got nil")
130 }
131 if err := proto.SetExtension(msg, pb.E_X215, 12); err == nil {
132 t.Error("expected extension err")
133 }
134 if err := proto.SetExtension(msg, pb.E_Ext_More, 12); err == nil {
135 t.Error("expected some sort of type mismatch error, got nil")
136 }
137}
David Symonds82b6f0b2015-03-03 06:33:00 +1100138
139func TestNilExtension(t *testing.T) {
140 msg := &pb.MyMessage{
141 Count: proto.Int32(1),
142 }
143 if err := proto.SetExtension(msg, pb.E_Ext_Text, proto.String("hello")); err != nil {
144 t.Fatal(err)
145 }
146 if err := proto.SetExtension(msg, pb.E_Ext_More, (*pb.Ext)(nil)); err == nil {
147 t.Error("expected SetExtension to fail due to a nil extension")
148 } else if want := "proto: SetExtension called with nil value of type *testdata.Ext"; err.Error() != want {
149 t.Errorf("expected error %v, got %v", want, err)
150 }
151 // Note: if the behavior of Marshal is ever changed to ignore nil extensions, update
152 // this test to verify that E_Ext_Text is properly propagated through marshal->unmarshal.
153}