github.com/gogo/protobuf@v1.3.2/protoc-gen-gogo/testdata/extension_test.go (about)

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