| David Symonds | 8b1c6b7 | 2014-06-20 14:28:56 +1000 | [diff] [blame] | 1 | // Go support for Protocol Buffers - Google's data interchange format |
| 2 | // |
| 3 | // Copyright 2014 The Go Authors. All rights reserved. |
| David Symonds | 558f13f | 2014-11-24 10:28:53 +1100 | [diff] [blame] | 4 | // https://github.com/golang/protobuf |
| David Symonds | 8b1c6b7 | 2014-06-20 14:28:56 +1000 | [diff] [blame] | 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 | |
| David Symonds | 558f13f | 2014-11-24 10:28:53 +1100 | [diff] [blame] | 37 | "github.com/golang/protobuf/proto" |
| David Symonds | a8de284 | 2015-03-20 16:24:29 +1100 | [diff] [blame^] | 38 | pb "github.com/golang/protobuf/proto/testdata" |
| David Symonds | 8b1c6b7 | 2014-06-20 14:28:56 +1000 | [diff] [blame] | 39 | ) |
| 40 | |
| 41 | func TestGetExtensionsWithMissingExtensions(t *testing.T) { |
| 42 | msg := &pb.MyMessage{} |
| 43 | ext1 := &pb.Ext{} |
| 44 | if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil { |
| 45 | t.Fatalf("Could not set ext1: %s", ext1) |
| 46 | } |
| 47 | exts, err := proto.GetExtensions(msg, []*proto.ExtensionDesc{ |
| 48 | pb.E_Ext_More, |
| 49 | pb.E_Ext_Text, |
| 50 | }) |
| 51 | if err != nil { |
| 52 | t.Fatalf("GetExtensions() failed: %s", err) |
| 53 | } |
| 54 | if exts[0] != ext1 { |
| 55 | t.Errorf("ext1 not in returned extensions: %T %v", exts[0], exts[0]) |
| 56 | } |
| 57 | if exts[1] != nil { |
| 58 | t.Errorf("ext2 in returned extensions: %T %v", exts[1], exts[1]) |
| 59 | } |
| 60 | } |
| David Symonds | ce441e6 | 2014-11-18 13:50:03 +1100 | [diff] [blame] | 61 | |
| 62 | func TestGetExtensionStability(t *testing.T) { |
| 63 | check := func(m *pb.MyMessage) bool { |
| 64 | ext1, err := proto.GetExtension(m, pb.E_Ext_More) |
| 65 | if err != nil { |
| 66 | t.Fatalf("GetExtension() failed: %s", err) |
| 67 | } |
| 68 | ext2, err := proto.GetExtension(m, pb.E_Ext_More) |
| 69 | if err != nil { |
| 70 | t.Fatalf("GetExtension() failed: %s", err) |
| 71 | } |
| 72 | return ext1 == ext2 |
| 73 | } |
| 74 | msg := &pb.MyMessage{Count: proto.Int32(4)} |
| 75 | ext0 := &pb.Ext{} |
| 76 | if err := proto.SetExtension(msg, pb.E_Ext_More, ext0); err != nil { |
| 77 | t.Fatalf("Could not set ext1: %s", ext0) |
| 78 | } |
| 79 | if !check(msg) { |
| 80 | t.Errorf("GetExtension() not stable before marshaling") |
| 81 | } |
| 82 | bb, err := proto.Marshal(msg) |
| 83 | if err != nil { |
| 84 | t.Fatalf("Marshal() failed: %s", err) |
| 85 | } |
| 86 | msg1 := &pb.MyMessage{} |
| 87 | err = proto.Unmarshal(bb, msg1) |
| 88 | if err != nil { |
| 89 | t.Fatalf("Unmarshal() failed: %s", err) |
| 90 | } |
| 91 | if !check(msg1) { |
| 92 | t.Errorf("GetExtension() not stable after unmarshaling") |
| 93 | } |
| 94 | } |
| David Symonds | 904b440 | 2014-12-11 08:44:00 -0500 | [diff] [blame] | 95 | |
| 96 | func TestExtensionsRoundTrip(t *testing.T) { |
| 97 | msg := &pb.MyMessage{} |
| 98 | ext1 := &pb.Ext{ |
| 99 | Data: proto.String("hi"), |
| 100 | } |
| 101 | ext2 := &pb.Ext{ |
| 102 | Data: proto.String("there"), |
| 103 | } |
| 104 | exists := proto.HasExtension(msg, pb.E_Ext_More) |
| 105 | if exists { |
| 106 | t.Error("Extension More present unexpectedly") |
| 107 | } |
| 108 | if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil { |
| 109 | t.Error(err) |
| 110 | } |
| 111 | if err := proto.SetExtension(msg, pb.E_Ext_More, ext2); err != nil { |
| 112 | t.Error(err) |
| 113 | } |
| 114 | e, err := proto.GetExtension(msg, pb.E_Ext_More) |
| 115 | if err != nil { |
| 116 | t.Error(err) |
| 117 | } |
| 118 | x, ok := e.(*pb.Ext) |
| 119 | if !ok { |
| 120 | t.Errorf("e has type %T, expected testdata.Ext", e) |
| 121 | } else if *x.Data != "there" { |
| 122 | t.Errorf("SetExtension failed to overwrite, got %+v, not 'there'", x) |
| 123 | } |
| 124 | proto.ClearExtension(msg, pb.E_Ext_More) |
| 125 | if _, err = proto.GetExtension(msg, pb.E_Ext_More); err != proto.ErrMissingExtension { |
| 126 | t.Errorf("got %v, expected ErrMissingExtension", e) |
| 127 | } |
| 128 | if _, err := proto.GetExtension(msg, pb.E_X215); err == nil { |
| 129 | t.Error("expected bad extension error, got nil") |
| 130 | } |
| 131 | if err := proto.SetExtension(msg, pb.E_X215, 12); err == nil { |
| 132 | t.Error("expected extension err") |
| 133 | } |
| 134 | if err := proto.SetExtension(msg, pb.E_Ext_More, 12); err == nil { |
| 135 | t.Error("expected some sort of type mismatch error, got nil") |
| 136 | } |
| 137 | } |
| David Symonds | 82b6f0b | 2015-03-03 06:33:00 +1100 | [diff] [blame] | 138 | |
| 139 | func TestNilExtension(t *testing.T) { |
| 140 | msg := &pb.MyMessage{ |
| 141 | Count: proto.Int32(1), |
| 142 | } |
| 143 | if err := proto.SetExtension(msg, pb.E_Ext_Text, proto.String("hello")); err != nil { |
| 144 | t.Fatal(err) |
| 145 | } |
| 146 | if err := proto.SetExtension(msg, pb.E_Ext_More, (*pb.Ext)(nil)); err == nil { |
| 147 | t.Error("expected SetExtension to fail due to a nil extension") |
| 148 | } else if want := "proto: SetExtension called with nil value of type *testdata.Ext"; err.Error() != want { |
| 149 | t.Errorf("expected error %v, got %v", want, err) |
| 150 | } |
| 151 | // Note: if the behavior of Marshal is ever changed to ignore nil extensions, update |
| 152 | // this test to verify that E_Ext_Text is properly propagated through marshal->unmarshal. |
| 153 | } |