...

Source file src/github.com/gogo/protobuf/proto/discard_test.go

Documentation: github.com/gogo/protobuf/proto

     1  // Go support for Protocol Buffers - Google's data interchange format
     2  //
     3  // Copyright 2017 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  package proto_test
    33  
    34  import (
    35  	"testing"
    36  
    37  	"github.com/gogo/protobuf/proto"
    38  	proto3pb "github.com/gogo/protobuf/proto/proto3_proto"
    39  	pb "github.com/gogo/protobuf/proto/test_proto"
    40  )
    41  
    42  func TestDiscardUnknown(t *testing.T) {
    43  	tests := []struct {
    44  		desc     string
    45  		in, want proto.Message
    46  	}{{
    47  		desc: "Nil",
    48  		in:   nil, want: nil, // Should not panic
    49  	}, {
    50  		desc: "NilPtr",
    51  		in:   (*proto3pb.Message)(nil), want: (*proto3pb.Message)(nil), // Should not panic
    52  	}, {
    53  		desc: "Nested",
    54  		in: &proto3pb.Message{
    55  			Name:             "Aaron",
    56  			Nested:           &proto3pb.Nested{Cute: true, XXX_unrecognized: []byte("blah")},
    57  			XXX_unrecognized: []byte("blah"),
    58  		},
    59  		want: &proto3pb.Message{
    60  			Name:   "Aaron",
    61  			Nested: &proto3pb.Nested{Cute: true},
    62  		},
    63  	}, {
    64  		desc: "Slice",
    65  		in: &proto3pb.Message{
    66  			Name: "Aaron",
    67  			Children: []*proto3pb.Message{
    68  				{Name: "Sarah", XXX_unrecognized: []byte("blah")},
    69  				{Name: "Abraham", XXX_unrecognized: []byte("blah")},
    70  			},
    71  			XXX_unrecognized: []byte("blah"),
    72  		},
    73  		want: &proto3pb.Message{
    74  			Name: "Aaron",
    75  			Children: []*proto3pb.Message{
    76  				{Name: "Sarah"},
    77  				{Name: "Abraham"},
    78  			},
    79  		},
    80  	}, {
    81  		desc: "OneOf",
    82  		in: &pb.Communique{
    83  			Union: &pb.Communique_Msg{Msg: &pb.Strings{
    84  				StringField:      proto.String("123"),
    85  				XXX_unrecognized: []byte("blah"),
    86  			}},
    87  			XXX_unrecognized: []byte("blah"),
    88  		},
    89  		want: &pb.Communique{
    90  			Union: &pb.Communique_Msg{Msg: &pb.Strings{StringField: proto.String("123")}},
    91  		},
    92  	}, {
    93  		desc: "Map",
    94  		in: &pb.MessageWithMap{MsgMapping: map[int64]*pb.FloatingPoint{
    95  			0x4002: {
    96  				Exact:            proto.Bool(true),
    97  				XXX_unrecognized: []byte("blah"),
    98  			},
    99  		}},
   100  		want: &pb.MessageWithMap{MsgMapping: map[int64]*pb.FloatingPoint{
   101  			0x4002: {Exact: proto.Bool(true)},
   102  		}},
   103  	}, {
   104  		desc: "Extension",
   105  		in: func() proto.Message {
   106  			m := &pb.MyMessage{
   107  				Count: proto.Int32(42),
   108  				Somegroup: &pb.MyMessage_SomeGroup{
   109  					GroupField:       proto.Int32(6),
   110  					XXX_unrecognized: []byte("blah"),
   111  				},
   112  				XXX_unrecognized: []byte("blah"),
   113  			}
   114  			proto.SetExtension(m, pb.E_Ext_More, &pb.Ext{
   115  				Data:             proto.String("extension"),
   116  				XXX_unrecognized: []byte("blah"),
   117  			})
   118  			return m
   119  		}(),
   120  		want: func() proto.Message {
   121  			m := &pb.MyMessage{
   122  				Count:     proto.Int32(42),
   123  				Somegroup: &pb.MyMessage_SomeGroup{GroupField: proto.Int32(6)},
   124  			}
   125  			proto.SetExtension(m, pb.E_Ext_More, &pb.Ext{Data: proto.String("extension")})
   126  			return m
   127  		}(),
   128  	}}
   129  
   130  	// Test the legacy code path.
   131  	for _, tt := range tests {
   132  		// Clone the input so that we don't alter the original.
   133  		in := tt.in
   134  		if in != nil {
   135  			in = proto.Clone(tt.in)
   136  		}
   137  
   138  		var m LegacyMessage
   139  		m.Message, _ = in.(*proto3pb.Message)
   140  		m.Communique, _ = in.(*pb.Communique)
   141  		m.MessageWithMap, _ = in.(*pb.MessageWithMap)
   142  		m.MyMessage, _ = in.(*pb.MyMessage)
   143  		proto.DiscardUnknown(&m)
   144  		if !proto.Equal(in, tt.want) {
   145  			t.Errorf("test %s/Legacy, expected unknown fields to be discarded\ngot  %v\nwant %v", tt.desc, in, tt.want)
   146  		}
   147  	}
   148  
   149  	for _, tt := range tests {
   150  		proto.DiscardUnknown(tt.in)
   151  		if !proto.Equal(tt.in, tt.want) {
   152  			t.Errorf("test %s, expected unknown fields to be discarded\ngot  %v\nwant %v", tt.desc, tt.in, tt.want)
   153  		}
   154  	}
   155  }
   156  
   157  // LegacyMessage is a proto.Message that has several nested messages.
   158  // This does not have the XXX_DiscardUnknown method and so forces DiscardUnknown
   159  // to use the legacy fallback logic.
   160  type LegacyMessage struct {
   161  	Message        *proto3pb.Message
   162  	Communique     *pb.Communique
   163  	MessageWithMap *pb.MessageWithMap
   164  	MyMessage      *pb.MyMessage
   165  }
   166  
   167  func (m *LegacyMessage) Reset()         { *m = LegacyMessage{} }
   168  func (m *LegacyMessage) String() string { return proto.CompactTextString(m) }
   169  func (*LegacyMessage) ProtoMessage()    {}
   170  

View as plain text