1// Copyright 2020 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package proto_test 6 7import ( 8 "testing" 9 10 "google.golang.org/protobuf/proto" 11 "google.golang.org/protobuf/reflect/protoreflect" 12 13 testpb "google.golang.org/protobuf/internal/testprotos/test" 14) 15 16// TestNil tests for boundary conditions when nil and typed-nil messages 17// are passed to various top-level functions. 18// These tests are not necessarily a statement of proper behavior, 19// but exist to detect accidental changes in behavior. 20func TestNil(t *testing.T) { 21 nilMsg := (*testpb.TestAllExtensions)(nil) 22 extType := testpb.E_OptionalBool 23 extRanger := func(protoreflect.ExtensionType, interface{}) bool { return true } 24 25 tests := []struct { 26 label string 27 test func() 28 panic bool 29 }{{ 30 label: "Size", 31 test: func() { proto.Size(nil) }, 32 }, { 33 label: "Size", 34 test: func() { proto.Size(nilMsg) }, 35 }, { 36 label: "Marshal", 37 test: func() { proto.Marshal(nil) }, 38 }, { 39 label: "Marshal", 40 test: func() { proto.Marshal(nilMsg) }, 41 }, { 42 label: "Unmarshal", 43 test: func() { proto.Unmarshal(nil, nil) }, 44 panic: true, 45 }, { 46 label: "Unmarshal", 47 test: func() { proto.Unmarshal(nil, nilMsg) }, 48 panic: true, 49 }, { 50 label: "Merge", 51 test: func() { proto.Merge(nil, nil) }, 52 panic: true, 53 }, { 54 label: "Merge", 55 test: func() { proto.Merge(nil, nilMsg) }, 56 panic: true, 57 }, { 58 label: "Merge", 59 test: func() { proto.Merge(nilMsg, nil) }, 60 panic: true, 61 }, { 62 label: "Merge", 63 test: func() { proto.Merge(nilMsg, nilMsg) }, 64 panic: true, 65 }, { 66 label: "Clone", 67 test: func() { proto.Clone(nil) }, 68 }, { 69 label: "Clone", 70 test: func() { proto.Clone(nilMsg) }, 71 }, { 72 label: "Equal", 73 test: func() { proto.Equal(nil, nil) }, 74 }, { 75 label: "Equal", 76 test: func() { proto.Equal(nil, nilMsg) }, 77 }, { 78 label: "Equal", 79 test: func() { proto.Equal(nilMsg, nil) }, 80 }, { 81 label: "Equal", 82 test: func() { proto.Equal(nilMsg, nilMsg) }, 83 }, { 84 label: "Reset", 85 test: func() { proto.Reset(nil) }, 86 panic: true, 87 }, { 88 label: "Reset", 89 test: func() { proto.Reset(nilMsg) }, 90 panic: true, 91 }, { 92 label: "HasExtension", 93 test: func() { proto.HasExtension(nil, nil) }, 94 }, { 95 label: "HasExtension", 96 test: func() { proto.HasExtension(nil, extType) }, 97 }, { 98 label: "HasExtension", 99 test: func() { proto.HasExtension(nilMsg, nil) }, 100 }, { 101 label: "HasExtension", 102 test: func() { proto.HasExtension(nilMsg, extType) }, 103 }, { 104 label: "GetExtension", 105 test: func() { proto.GetExtension(nil, nil) }, 106 panic: true, 107 }, { 108 label: "GetExtension", 109 test: func() { proto.GetExtension(nil, extType) }, 110 }, { 111 label: "GetExtension", 112 test: func() { proto.GetExtension(nilMsg, nil) }, 113 panic: true, 114 }, { 115 label: "GetExtension", 116 test: func() { proto.GetExtension(nilMsg, extType) }, 117 }, { 118 label: "SetExtension", 119 test: func() { proto.SetExtension(nil, nil, true) }, 120 panic: true, 121 }, { 122 label: "SetExtension", 123 test: func() { proto.SetExtension(nil, extType, true) }, 124 panic: true, 125 }, { 126 label: "SetExtension", 127 test: func() { proto.SetExtension(nilMsg, nil, true) }, 128 panic: true, 129 }, { 130 label: "SetExtension", 131 test: func() { proto.SetExtension(nilMsg, extType, true) }, 132 panic: true, 133 }, { 134 label: "ClearExtension", 135 test: func() { proto.ClearExtension(nil, nil) }, 136 panic: true, 137 }, { 138 label: "ClearExtension", 139 test: func() { proto.ClearExtension(nil, extType) }, 140 panic: true, 141 }, { 142 label: "ClearExtension", 143 test: func() { proto.ClearExtension(nilMsg, nil) }, 144 panic: true, 145 }, { 146 label: "ClearExtension", 147 test: func() { proto.ClearExtension(nilMsg, extType) }, 148 panic: true, 149 }, { 150 label: "RangeExtensions", 151 test: func() { proto.RangeExtensions(nil, nil) }, 152 }, { 153 label: "RangeExtensions", 154 test: func() { proto.RangeExtensions(nil, extRanger) }, 155 }, { 156 label: "RangeExtensions", 157 test: func() { proto.RangeExtensions(nilMsg, nil) }, 158 }, { 159 label: "RangeExtensions", 160 test: func() { proto.RangeExtensions(nilMsg, extRanger) }, 161 }} 162 163 for _, tt := range tests { 164 t.Run(tt.label, func(t *testing.T) { 165 defer func() { 166 switch gotPanic := recover() != nil; { 167 case gotPanic && !tt.panic: 168 t.Errorf("unexpected panic") 169 case !gotPanic && tt.panic: 170 t.Errorf("expected panic") 171 } 172 }() 173 tt.test() 174 }) 175 } 176} 177