github.com/gogo/protobuf@v1.3.2/test/required/requiredexamplepb_test.go (about) 1 // Protocol Buffers for Go with Gadgets 2 // 3 // Copyright (c) 2013, The GoGo Authors. All rights reserved. 4 // http://github.com/gogo/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 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 package required 30 31 import ( 32 "github.com/gogo/protobuf/proto" 33 "github.com/gogo/protobuf/test" 34 "math/rand" 35 "reflect" 36 "strconv" 37 "testing" 38 "time" 39 ) 40 41 func TestMarshalToErrorsWhenRequiredFieldIsNotPresent(t *testing.T) { 42 data := RequiredExample{} 43 buf, err := proto.Marshal(&data) 44 if err == nil { 45 t.Fatalf("err == nil; was %v instead", err) 46 } 47 if err.Error() != `proto: required field "theRequiredString" not set` { 48 t.Fatalf(`err.Error() != "proto: required field "theRequiredString" not set"; was "%s" instead`, err.Error()) 49 } 50 if len(buf) != 0 { 51 t.Fatalf(`len(buf) != 0; was %d instead`, len(buf)) 52 } 53 } 54 55 func TestMarshalToSucceedsWhenRequiredFieldIsPresent(t *testing.T) { 56 data := RequiredExample{ 57 TheRequiredString: proto.String("present"), 58 } 59 buf, err := proto.Marshal(&data) 60 if err != nil { 61 t.Fatalf("err != nil; was %v instead", err) 62 } 63 if len(buf) == 0 { 64 t.Fatalf(`len(buf) == 0; expected nonzero`) 65 } 66 } 67 68 func TestUnmarshalErrorsWhenRequiredFieldIsNotPresent(t *testing.T) { 69 missingRequiredField := []byte{0x12, 0x8, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c} 70 data := RequiredExample{} 71 err := proto.Unmarshal(missingRequiredField, &data) 72 if err == nil { 73 t.Fatalf("err == nil; was %v instead", err) 74 } 75 if err.Error() != `proto: required field "theRequiredString" not set` { 76 t.Fatalf(`err.Error() != "proto: required field "theRequiredString" not set"; was "%s" instead`, err.Error()) 77 } 78 } 79 80 func TestUnmarshalSucceedsWhenRequiredIsNotPresent(t *testing.T) { 81 dataOut := RequiredExample{ 82 TheRequiredString: proto.String("present"), 83 } 84 encodedMessage, err := proto.Marshal(&dataOut) 85 if err != nil { 86 t.Fatalf("Unexpected error when marshalling dataOut: %v", err) 87 } 88 dataIn := RequiredExample{} 89 err = proto.Unmarshal(encodedMessage, &dataIn) 90 if err != nil { 91 t.Fatalf("err != nil; was %v instead", err) 92 } 93 } 94 95 func TestUnmarshalPopulatedOptionalFieldsAsRequiredSucceeds(t *testing.T) { 96 r := rand.New(rand.NewSource(time.Now().UnixNano())) 97 dataOut := test.NewPopulatedNidOptNative(r, true) 98 encodedMessage, err := proto.Marshal(dataOut) 99 if err != nil { 100 t.Fatalf("Unexpected error when marshalling dataOut: %v", err) 101 } 102 dataIn := NidOptNative{} 103 err = proto.Unmarshal(encodedMessage, &dataIn) 104 if err != nil { 105 t.Fatalf("err != nil; was %v instead", err) 106 } 107 } 108 109 func TestUnmarshalPartiallyPopulatedOptionalFieldsFails(t *testing.T) { 110 // Fill in all fields, then randomly remove one. 111 dataOut := &test.NinOptNative{ 112 Field1: proto.Float64(0), 113 Field2: proto.Float32(0), 114 Field3: proto.Int32(0), 115 Field4: proto.Int64(0), 116 Field5: proto.Uint32(0), 117 Field6: proto.Uint64(0), 118 Field7: proto.Int32(0), 119 Field8: proto.Int64(0), 120 Field9: proto.Uint32(0), 121 Field10: proto.Int32(0), 122 Field11: proto.Uint64(0), 123 Field12: proto.Int64(0), 124 Field13: proto.Bool(false), 125 Field14: proto.String("0"), 126 Field15: []byte("0"), 127 } 128 r := rand.New(rand.NewSource(time.Now().UnixNano())) 129 fieldName := "Field" + strconv.Itoa(r.Intn(15)+1) 130 field := reflect.ValueOf(dataOut).Elem().FieldByName(fieldName) 131 fieldType := field.Type() 132 field.Set(reflect.Zero(fieldType)) 133 encodedMessage, err := proto.Marshal(dataOut) 134 if err != nil { 135 t.Fatalf("Unexpected error when marshalling dataOut: %v", err) 136 } 137 dataIn := NidOptNative{} 138 err = proto.Unmarshal(encodedMessage, &dataIn) 139 if err.Error() != `proto: required field "`+fieldName+`" not set` { 140 t.Fatalf(`err.Error() != "proto: required field "`+fieldName+`" not set"; was "%s" instead`, err.Error()) 141 } 142 } 143 144 func TestMarshalFailsWithoutAllFieldsSet(t *testing.T) { 145 r := rand.New(rand.NewSource(time.Now().UnixNano())) 146 dataOut := NewPopulatedNinOptNative(r, true) 147 fieldName := "Field" + strconv.Itoa(r.Intn(15)+1) 148 field := reflect.ValueOf(dataOut).Elem().FieldByName(fieldName) 149 fieldType := field.Type() 150 field.Set(reflect.Zero(fieldType)) 151 encodedMessage, err := proto.Marshal(dataOut) 152 if err.Error() != `proto: required field "`+fieldName+`" not set` { 153 t.Fatalf(`err.Error() != "proto: required field "`+fieldName+`" not set"; was "%s" instead`, err.Error()) 154 } 155 if len(encodedMessage) > 0 { 156 t.Fatalf("Got some bytes from marshal, expected none.") 157 } 158 } 159 160 func TestMissingFieldsOnRepeatedNestedTypes(t *testing.T) { 161 r := rand.New(rand.NewSource(time.Now().UnixNano())) 162 dataOut := &NestedNinOptNative{ 163 NestedNinOpts: []*NinOptNative{ 164 NewPopulatedNinOptNative(r, true), 165 NewPopulatedNinOptNative(r, true), 166 NewPopulatedNinOptNative(r, true), 167 }, 168 } 169 middle := dataOut.GetNestedNinOpts()[1] 170 fieldName := "Field" + strconv.Itoa(r.Intn(15)+1) 171 field := reflect.ValueOf(middle).Elem().FieldByName(fieldName) 172 fieldType := field.Type() 173 field.Set(reflect.Zero(fieldType)) 174 encodedMessage, err := proto.Marshal(dataOut) 175 if err.Error() != `proto: required field "`+fieldName+`" not set` { 176 t.Fatalf(`err.Error() != "proto: required field "`+fieldName+`" not set"; was "%s" instead`, err.Error()) 177 } 178 if len(encodedMessage) > 0 { 179 t.Fatalf("Got some bytes from marshal, expected none.") 180 } 181 }