// Go support for Protocol Buffers - Google's data interchange format // // Copyright 2010 The Go Authors. All rights reserved. // https://github.com/golang/protobuf // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Test that we can use protocol buffers that use extensions. package testdata /* import ( "bytes" "regexp" "testing" "github.com/golang/protobuf/proto" base "extension_base.pb" user "extension_user.pb" ) func TestSingleFieldExtension(t *testing.T) { bm := &base.BaseMessage{ Height: proto.Int32(178), } // Use extension within scope of another type. vol := proto.Uint32(11) err := proto.SetExtension(bm, user.E_LoudMessage_Volume, vol) if err != nil { t.Fatal("Failed setting extension:", err) } buf, err := proto.Marshal(bm) if err != nil { t.Fatal("Failed encoding message with extension:", err) } bm_new := new(base.BaseMessage) if err := proto.Unmarshal(buf, bm_new); err != nil { t.Fatal("Failed decoding message with extension:", err) } if !proto.HasExtension(bm_new, user.E_LoudMessage_Volume) { t.Fatal("Decoded message didn't contain extension.") } vol_out, err := proto.GetExtension(bm_new, user.E_LoudMessage_Volume) if err != nil { t.Fatal("Failed getting extension:", err) } if v := vol_out.(*uint32); *v != *vol { t.Errorf("vol_out = %v, expected %v", *v, *vol) } proto.ClearExtension(bm_new, user.E_LoudMessage_Volume) if proto.HasExtension(bm_new, user.E_LoudMessage_Volume) { t.Fatal("Failed clearing extension.") } } func TestMessageExtension(t *testing.T) { bm := &base.BaseMessage{ Height: proto.Int32(179), } // Use extension that is itself a message. um := &user.UserMessage{ Name: proto.String("Dave"), Rank: proto.String("Major"), } err := proto.SetExtension(bm, user.E_LoginMessage_UserMessage, um) if err != nil { t.Fatal("Failed setting extension:", err) } buf, err := proto.Marshal(bm) if err != nil { t.Fatal("Failed encoding message with extension:", err) } bm_new := new(base.BaseMessage) if err := proto.Unmarshal(buf, bm_new); err != nil { t.Fatal("Failed decoding message with extension:", err) } if !proto.HasExtension(bm_new, user.E_LoginMessage_UserMessage) { t.Fatal("Decoded message didn't contain extension.") } um_out, err := proto.GetExtension(bm_new, user.E_LoginMessage_UserMessage) if err != nil { t.Fatal("Failed getting extension:", err) } if n := um_out.(*user.UserMessage).Name; *n != *um.Name { t.Errorf("um_out.Name = %q, expected %q", *n, *um.Name) } if r := um_out.(*user.UserMessage).Rank; *r != *um.Rank { t.Errorf("um_out.Rank = %q, expected %q", *r, *um.Rank) } proto.ClearExtension(bm_new, user.E_LoginMessage_UserMessage) if proto.HasExtension(bm_new, user.E_LoginMessage_UserMessage) { t.Fatal("Failed clearing extension.") } } func TestTopLevelExtension(t *testing.T) { bm := &base.BaseMessage{ Height: proto.Int32(179), } width := proto.Int32(17) err := proto.SetExtension(bm, user.E_Width, width) if err != nil { t.Fatal("Failed setting extension:", err) } buf, err := proto.Marshal(bm) if err != nil { t.Fatal("Failed encoding message with extension:", err) } bm_new := new(base.BaseMessage) if err := proto.Unmarshal(buf, bm_new); err != nil { t.Fatal("Failed decoding message with extension:", err) } if !proto.HasExtension(bm_new, user.E_Width) { t.Fatal("Decoded message didn't contain extension.") } width_out, err := proto.GetExtension(bm_new, user.E_Width) if err != nil { t.Fatal("Failed getting extension:", err) } if w := width_out.(*int32); *w != *width { t.Errorf("width_out = %v, expected %v", *w, *width) } proto.ClearExtension(bm_new, user.E_Width) if proto.HasExtension(bm_new, user.E_Width) { t.Fatal("Failed clearing extension.") } } func TestMessageSetWireFormat(t *testing.T) { osm := new(base.OldStyleMessage) osp := &user.OldStyleParcel{ Name: proto.String("Dave"), Height: proto.Int32(178), } err := proto.SetExtension(osm, user.E_OldStyleParcel_MessageSetExtension, osp) if err != nil { t.Fatal("Failed setting extension:", err) } buf, err := proto.Marshal(osm) if err != nil { t.Fatal("Failed encoding message:", err) } // Data generated from Python implementation. expected := []byte{ 11, 16, 209, 15, 26, 9, 10, 4, 68, 97, 118, 101, 16, 178, 1, 12, } if !bytes.Equal(expected, buf) { t.Errorf("Encoding mismatch.\nwant %+v\n got %+v", expected, buf) } // Check that it is restored correctly. osm = new(base.OldStyleMessage) if err := proto.Unmarshal(buf, osm); err != nil { t.Fatal("Failed decoding message:", err) } osp_out, err := proto.GetExtension(osm, user.E_OldStyleParcel_MessageSetExtension) if err != nil { t.Fatal("Failed getting extension:", err) } osp = osp_out.(*user.OldStyleParcel) if *osp.Name != "Dave" || *osp.Height != 178 { t.Errorf("Retrieved extension from decoded message is not correct: %+v", osp) } } func main() { // simpler than rigging up gotest testing.Main(regexp.MatchString, []testing.InternalTest{ {"TestSingleFieldExtension", TestSingleFieldExtension}, {"TestMessageExtension", TestMessageExtension}, {"TestTopLevelExtension", TestTopLevelExtension}, }, []testing.InternalBenchmark{}, []testing.InternalExample{}) } */