1 // Go support for Protocol Buffers - Google's data interchange format
3 // Copyright 2010 Google Inc. All rights reserved.
4 // http://code.google.com/p/goprotobuf/
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are
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
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.
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.
39 "goprotobuf.googlecode.com/hg/proto"
41 pb "./testdata/_obj/test_proto"
44 func newTestMessage() *pb.MyMessage {
46 Count: proto.Int32(42),
47 Name: proto.String("Dave"),
48 Quote: proto.String(`"I didn't want to go."`),
49 Pet: []string{"bunny", "kitty", "horsey"},
50 Inner: &pb.InnerMessage{
51 Host: proto.String("footrest.syd"),
52 Port: proto.Int32(7001),
53 Connected: proto.Bool(true),
55 Others: []*pb.OtherMessage{
57 Key: proto.Int64(0xdeadbeef),
58 Value: []byte{1, 65, 7, 12},
61 Weight: proto.Float32(6.022),
62 Inner: &pb.InnerMessage{
63 Host: proto.String("lesha.mtv"),
64 Port: proto.Int32(8002),
68 Bikeshed: pb.NewMyMessage_Color(pb.MyMessage_BLUE),
69 Somegroup: &pb.MyMessage_SomeGroup{
70 GroupField: proto.Int32(8),
72 // 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},
77 Data: proto.String("Big gobs for big rats"),
79 if err := proto.SetExtension(msg, pb.E_Ext_More, ext); err != nil {
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")})
88 b = append(proto.EncodeVarint(104<<3|proto.WireBytes), b...)
89 proto.SetRawExtension(msg, 104, b)
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)
98 const text = `count: 42
100 quote: "\"I didn't want to go.\""
111 value: "\001A\007\014"
124 /* 2 unknown bytes */
126 [test_proto.Ext.more]: <
127 data: "Big gobs for big rats"
129 /* 13 unknown bytes */
130 tag104: "\t3G skiing"
131 /* 3 unknown bytes */
135 func TestMarshalTextFull(t *testing.T) {
136 buf := new(bytes.Buffer)
137 proto.MarshalText(buf, newTestMessage())
140 t.Errorf("Got:\n===\n%v===\nExpected:\n===\n%v===\n", s, text)
144 func compact(src string) string {
145 // s/[ \n]+/ /g; s/ $//;
146 dst := make([]byte, len(src))
147 space, comment := false, false
149 for i := 0; i < len(src); i++ {
150 if strings.HasPrefix(src[i:], "/*") {
155 if comment && strings.HasPrefix(src[i:], "*/") {
164 if c == ' ' || c == '\n' {
168 if j > 0 && (dst[j-1] == ':' || dst[j-1] == '<' || dst[j-1] == '{') {
186 return string(dst[0:j])
189 var compactText = compact(text)
191 func TestCompactText(t *testing.T) {
192 s := proto.CompactTextString(newTestMessage())
193 if s != compactText {
194 t.Errorf("Got:\n===\n%v===\nExpected:\n===\n%v\n===\n", s, compactText)
198 func TestStringEscaping(t *testing.T) {
199 testCases := []struct {
204 // Test data from C++ test (TextFormatTest.StringEscape).
205 // Single divergence: we don't escape apostrophes.
206 &pb.Strings{StringField: proto.String("\"A string with ' characters \n and \r newlines and \t tabs and \001 slashes \\ and multiple spaces")},
207 "string_field: \"\\\"A string with ' characters \\n and \\r newlines and \\t tabs and \\001 slashes \\\\ and multiple spaces\"\n",
210 // Test data from the same C++ test.
211 &pb.Strings{StringField: proto.String("\350\260\267\346\255\214")},
212 "string_field: \"\\350\\260\\267\\346\\255\\214\"\n",
216 for i, tc := range testCases {
218 proto.MarshalText(&buf, tc.in)
219 if s := buf.String(); s != tc.out {
220 t.Errorf("#%d: Got:\n%s\nExpected:\n%s\n", i, s, tc.out)