blob: 00f17f8a61bc91f52a564eef0d1b111ebf84744d [file] [log] [blame]
Rob Pikeaaa3a622010-03-20 22:32:34 -07001// 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
32package proto_test
33
34import (
35 "bytes"
David Symonds1d72f7a2011-08-19 18:28:52 +100036 "strings"
Rob Pikeaaa3a622010-03-20 22:32:34 -070037 "testing"
David Symondsaa922ff2011-07-19 14:58:06 +100038
39 "goprotobuf.googlecode.com/hg/proto"
40
41 pb "./testdata/_obj/test_proto"
Rob Pikeaaa3a622010-03-20 22:32:34 -070042)
43
David Symondsaa922ff2011-07-19 14:58:06 +100044func newTestMessage() *pb.MyMessage {
45 msg := &pb.MyMessage{
46 Count: proto.Int32(42),
47 Name: proto.String("Dave"),
48 Quote: proto.String(`"I didn't want to go."`),
Rob Pike9caa5b92010-05-11 16:04:57 -070049 Pet: []string{"bunny", "kitty", "horsey"},
David Symondsaa922ff2011-07-19 14:58:06 +100050 Inner: &pb.InnerMessage{
51 Host: proto.String("footrest.syd"),
52 Port: proto.Int32(7001),
53 Connected: proto.Bool(true),
Rob Pikeaaa3a622010-03-20 22:32:34 -070054 },
David Symondsaa922ff2011-07-19 14:58:06 +100055 Others: []*pb.OtherMessage{
56 &pb.OtherMessage{
57 Key: proto.Int64(0xdeadbeef),
Rob Pikeaaa3a622010-03-20 22:32:34 -070058 Value: []byte{1, 65, 7, 12},
59 },
David Symondsaa922ff2011-07-19 14:58:06 +100060 &pb.OtherMessage{
61 Weight: proto.Float32(6.022),
62 Inner: &pb.InnerMessage{
63 Host: proto.String("lesha.mtv"),
64 Port: proto.Int32(8002),
Rob Pikeaaa3a622010-03-20 22:32:34 -070065 },
66 },
67 },
David Symondsaa922ff2011-07-19 14:58:06 +100068 Bikeshed: pb.NewMyMessage_Color(pb.MyMessage_BLUE),
69 Somegroup: &pb.MyMessage_SomeGroup{
70 GroupField: proto.Int32(8),
David Symonds9f402812011-04-28 18:08:44 +100071 },
David Symonds1d72f7a2011-08-19 18:28:52 +100072 // One normally wouldn't do this.
73 // This is an undeclared tag 13, as a varint (wire type 0) with value 4.
74 XXX_unrecognized: []byte{13<<3 | 0, 4},
Rob Pikeaaa3a622010-03-20 22:32:34 -070075 }
David Symondsaa922ff2011-07-19 14:58:06 +100076 ext := &pb.Ext{
77 Data: proto.String("Big gobs for big rats"),
David Symondse37856c2011-06-22 12:52:53 +100078 }
David Symondsaa922ff2011-07-19 14:58:06 +100079 if err := proto.SetExtension(msg, pb.E_Ext_More, ext); err != nil {
David Symondse37856c2011-06-22 12:52:53 +100080 panic(err)
81 }
David Symonds1d72f7a2011-08-19 18:28:52 +100082
83 // Add an unknown extension. We marshal a pb.Ext, and fake the ID.
84 b, err := proto.Marshal(&pb.Ext{Data: proto.String("3G skiing")})
85 if err != nil {
86 panic(err)
87 }
88 b = append(proto.EncodeVarint(104<<3|proto.WireBytes), b...)
89 proto.SetRawExtension(msg, 104, b)
90
91 // Extensions can be plain fields, too, so let's test that.
92 b = append(proto.EncodeVarint(105<<3|proto.WireVarint), 19)
93 proto.SetRawExtension(msg, 105, b)
94
David Symondse37856c2011-06-22 12:52:53 +100095 return msg
Rob Pikeaaa3a622010-03-20 22:32:34 -070096}
97
98const text = `count: 42
99name: "Dave"
100quote: "\"I didn't want to go.\""
101pet: "bunny"
102pet: "kitty"
103pet: "horsey"
104inner: <
105 host: "footrest.syd"
106 port: 7001
107 connected: true
108>
109others: <
110 key: 3735928559
111 value: "\x01A\a\f"
112>
113others: <
114 weight: 6.022
115 inner: <
116 host: "lesha.mtv"
117 port: 8002
118 >
119>
120bikeshed: BLUE
David Symonds9f402812011-04-28 18:08:44 +1000121SomeGroup {
122 group_field: 8
123}
David Symonds1d72f7a2011-08-19 18:28:52 +1000124/* 2 unknown bytes */
125tag13: 4
126[test_proto.Ext.more]: <
David Symondse37856c2011-06-22 12:52:53 +1000127 data: "Big gobs for big rats"
128>
David Symonds1d72f7a2011-08-19 18:28:52 +1000129/* 13 unknown bytes */
130tag104: "\t3G skiing"
131/* 3 unknown bytes */
132tag105: 19
Rob Pikeaaa3a622010-03-20 22:32:34 -0700133`
134
135func TestMarshalTextFull(t *testing.T) {
136 buf := new(bytes.Buffer)
David Symondsaa922ff2011-07-19 14:58:06 +1000137 proto.MarshalText(buf, newTestMessage())
Rob Pikeaaa3a622010-03-20 22:32:34 -0700138 s := buf.String()
139 if s != text {
140 t.Errorf("Got:\n===\n%v===\nExpected:\n===\n%v===\n", s, text)
141 }
142}
143
144func compact(src string) string {
David Symondse37856c2011-06-22 12:52:53 +1000145 // s/[ \n]+/ /g; s/ $//;
Rob Pikeaaa3a622010-03-20 22:32:34 -0700146 dst := make([]byte, len(src))
David Symonds1d72f7a2011-08-19 18:28:52 +1000147 space, comment := false, false
Rob Pikeaaa3a622010-03-20 22:32:34 -0700148 j := 0
149 for i := 0; i < len(src); i++ {
David Symonds1d72f7a2011-08-19 18:28:52 +1000150 if strings.HasPrefix(src[i:], "/*") {
151 comment = true
152 i++
153 continue
154 }
155 if comment && strings.HasPrefix(src[i:], "*/") {
156 comment = false
157 i++
158 continue
159 }
160 if comment {
161 continue
162 }
Rob Pikeaaa3a622010-03-20 22:32:34 -0700163 c := src[i]
164 if c == ' ' || c == '\n' {
165 space = true
166 continue
167 }
David Symonds9f402812011-04-28 18:08:44 +1000168 if j > 0 && (dst[j-1] == ':' || dst[j-1] == '<' || dst[j-1] == '{') {
169 space = false
170 }
171 if c == '{' {
Rob Pikeaaa3a622010-03-20 22:32:34 -0700172 space = false
173 }
174 if space {
175 dst[j] = ' '
176 j++
177 space = false
178 }
179 dst[j] = c
180 j++
181 }
182 if space {
183 dst[j] = ' '
184 j++
185 }
186 return string(dst[0:j])
187}
188
189var compactText = compact(text)
190
191func TestCompactText(t *testing.T) {
David Symondsaa922ff2011-07-19 14:58:06 +1000192 s := proto.CompactTextString(newTestMessage())
Rob Pikeaaa3a622010-03-20 22:32:34 -0700193 if s != compactText {
194 t.Errorf("Got:\n===\n%v===\nExpected:\n===\n%v===\n", s, compactText)
195 }
196}
David Symonds1d72f7a2011-08-19 18:28:52 +1000197
198