initialise
[debian/goprotobuf.git] / compiler / testdata / extension_test.go
1 // Go support for Protocol Buffers - Google's data interchange format
2 //
3 // Copyright 2010 Google Inc.  All rights reserved.
4 // http://code.google.com/p/goprotobuf/
5 //
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
32 // Test that we can use protocol buffers that use extensions.
33
34 package main
35
36 import (
37         "bytes"
38         "regexp"
39         "testing"
40
41         "goprotobuf.googlecode.com/hg/proto"
42         base "extension_base.pb"
43         user "extension_user.pb"
44 )
45
46 func TestSingleFieldExtension(t *testing.T) {
47         bm := &base.BaseMessage{
48                 Height: proto.Int32(178),
49         }
50
51         // Use extension within scope of another type.
52         vol := proto.Uint32(11)
53         err := proto.SetExtension(bm, user.E_LoudMessage_Volume, vol)
54         if err != nil {
55                 t.Fatal("Failed setting extension:", err)
56         }
57         buf, err := proto.Marshal(bm)
58         if err != nil {
59                 t.Fatal("Failed encoding message with extension:", err)
60         }
61         bm_new := new(base.BaseMessage)
62         if err := proto.Unmarshal(buf, bm_new); err != nil {
63                 t.Fatal("Failed decoding message with extension:", err)
64         }
65         if !proto.HasExtension(bm_new, user.E_LoudMessage_Volume) {
66                 t.Fatal("Decoded message didn't contain extension.")
67         }
68         vol_out, err := proto.GetExtension(bm_new, user.E_LoudMessage_Volume)
69         if err != nil {
70                 t.Fatal("Failed getting extension:", err)
71         }
72         if v := vol_out.(*uint32); *v != *vol {
73                 t.Errorf("vol_out = %v, expected %v", *v, *vol)
74         }
75         proto.ClearExtension(bm_new, user.E_LoudMessage_Volume)
76         if proto.HasExtension(bm_new, user.E_LoudMessage_Volume) {
77                 t.Fatal("Failed clearing extension.")
78         }
79 }
80
81 func TestMessageExtension(t *testing.T) {
82         bm := &base.BaseMessage{
83                 Height: proto.Int32(179),
84         }
85
86         // Use extension that is itself a message.
87         um := &user.UserMessage{
88                 Name: proto.String("Dave"),
89                 Rank: proto.String("Major"),
90         }
91         err := proto.SetExtension(bm, user.E_LoginMessage_UserMessage, um)
92         if err != nil {
93                 t.Fatal("Failed setting extension:", err)
94         }
95         buf, err := proto.Marshal(bm)
96         if err != nil {
97                 t.Fatal("Failed encoding message with extension:", err)
98         }
99         bm_new := new(base.BaseMessage)
100         if err := proto.Unmarshal(buf, bm_new); err != nil {
101                 t.Fatal("Failed decoding message with extension:", err)
102         }
103         if !proto.HasExtension(bm_new, user.E_LoginMessage_UserMessage) {
104                 t.Fatal("Decoded message didn't contain extension.")
105         }
106         um_out, err := proto.GetExtension(bm_new, user.E_LoginMessage_UserMessage)
107         if err != nil {
108                 t.Fatal("Failed getting extension:", err)
109         }
110         if n := um_out.(*user.UserMessage).Name; *n != *um.Name {
111                 t.Errorf("um_out.Name = %q, expected %q", *n, *um.Name)
112         }
113         if r := um_out.(*user.UserMessage).Rank; *r != *um.Rank {
114                 t.Errorf("um_out.Rank = %q, expected %q", *r, *um.Rank)
115         }
116         proto.ClearExtension(bm_new, user.E_LoginMessage_UserMessage)
117         if proto.HasExtension(bm_new, user.E_LoginMessage_UserMessage) {
118                 t.Fatal("Failed clearing extension.")
119         }
120 }
121
122 func TestTopLevelExtension(t *testing.T) {
123         bm := &base.BaseMessage{
124                 Height: proto.Int32(179),
125         }
126
127         width := proto.Int32(17)
128         err := proto.SetExtension(bm, user.E_Width, width)
129         if err != nil {
130                 t.Fatal("Failed setting extension:", err)
131         }
132         buf, err := proto.Marshal(bm)
133         if err != nil {
134                 t.Fatal("Failed encoding message with extension:", err)
135         }
136         bm_new := new(base.BaseMessage)
137         if err := proto.Unmarshal(buf, bm_new); err != nil {
138                 t.Fatal("Failed decoding message with extension:", err)
139         }
140         if !proto.HasExtension(bm_new, user.E_Width) {
141                 t.Fatal("Decoded message didn't contain extension.")
142         }
143         width_out, err := proto.GetExtension(bm_new, user.E_Width)
144         if err != nil {
145                 t.Fatal("Failed getting extension:", err)
146         }
147         if w := width_out.(*int32); *w != *width {
148                 t.Errorf("width_out = %v, expected %v", *w, *width)
149         }
150         proto.ClearExtension(bm_new, user.E_Width)
151         if proto.HasExtension(bm_new, user.E_Width) {
152                 t.Fatal("Failed clearing extension.")
153         }
154 }
155
156 func TestMessageSetWireFormat(t *testing.T) {
157         osm := new(base.OldStyleMessage)
158         osp := &user.OldStyleParcel{
159                 Name:   proto.String("Dave"),
160                 Height: proto.Int32(178),
161         }
162
163         err := proto.SetExtension(osm, user.E_OldStyleParcel_MessageSetExtension, osp)
164         if err != nil {
165                 t.Fatal("Failed setting extension:", err)
166         }
167
168         buf, err := proto.Marshal(osm)
169         if err != nil {
170                 t.Fatal("Failed encoding message:", err)
171         }
172
173         // Data generated from Python implementation.
174         expected := []byte{
175                 11, 16, 209, 15, 26, 9, 10, 4, 68, 97, 118, 101, 16, 178, 1, 12,
176         }
177
178         if !bytes.Equal(expected, buf) {
179                 t.Errorf("Encoding mismatch.\nwant %+v\n got %+v", expected, buf)
180         }
181
182         // Check that it is restored correctly.
183         osm = new(base.OldStyleMessage)
184         if err := proto.Unmarshal(buf, osm); err != nil {
185                 t.Fatal("Failed decoding message:", err)
186         }
187         osp_out, err := proto.GetExtension(osm, user.E_OldStyleParcel_MessageSetExtension)
188         if err != nil {
189                 t.Fatal("Failed getting extension:", err)
190         }
191         osp = osp_out.(*user.OldStyleParcel)
192         if *osp.Name != "Dave" || *osp.Height != 178 {
193                 t.Errorf("Retrieved extension from decoded message is not correct: %+v", osp)
194         }
195 }
196
197 func main() {
198         // simpler than rigging up gotest
199         testing.Main(regexp.MatchString, []testing.InternalTest{
200                 {"TestSingleFieldExtension", TestSingleFieldExtension},
201                 {"TestMessageExtension", TestMessageExtension},
202                 {"TestTopLevelExtension", TestTopLevelExtension},
203         },
204                 []testing.InternalBenchmark{})
205 }