github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/common/tools/protolator/json_test.go (about) 1 /* 2 Copyright IBM Corp. 2017 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package protolator 18 19 import ( 20 "bytes" 21 "encoding/json" 22 "fmt" 23 "math" 24 "reflect" 25 "testing" 26 27 "github.com/hyperledger/fabric/common/tools/protolator/testprotos" 28 29 "github.com/golang/protobuf/proto" 30 "github.com/stretchr/testify/assert" 31 ) 32 33 type testProtoPlainFieldFactory struct { 34 fromPrefix string 35 toPrefix string 36 fromError error 37 toError error 38 } 39 40 func (tpff *testProtoPlainFieldFactory) Handles(msg proto.Message, fieldName string, fieldType reflect.Type, fieldValue reflect.Value) bool { 41 return fieldName == "plain_field" 42 } 43 44 func (tpff *testProtoPlainFieldFactory) NewProtoField(msg proto.Message, fieldName string, fieldType reflect.Type, fieldValue reflect.Value) (protoField, error) { 45 return &plainField{ 46 baseField: baseField{ 47 msg: msg, 48 name: fieldName, 49 fType: reflect.TypeOf(""), 50 vType: fieldType, 51 value: fieldValue, 52 }, 53 populateFrom: func(source interface{}, destType reflect.Type) (reflect.Value, error) { 54 sourceAsString := source.(string) 55 return reflect.ValueOf(tpff.fromPrefix + sourceAsString), tpff.fromError 56 }, 57 populateTo: func(source reflect.Value) (interface{}, error) { 58 return tpff.toPrefix + source.Interface().(string), tpff.toError 59 }, 60 }, nil 61 } 62 63 func TestSimpleMsgPlainField(t *testing.T) { 64 fromPrefix := "from" 65 toPrefix := "to" 66 tppff := &testProtoPlainFieldFactory{ 67 fromPrefix: fromPrefix, 68 toPrefix: toPrefix, 69 } 70 71 fieldFactories = []protoFieldFactory{tppff} 72 73 pfValue := "foo" 74 startMsg := &testprotos.SimpleMsg{ 75 PlainField: pfValue, 76 MapField: map[string]string{"1": "2"}, 77 SliceField: []string{"a", "b"}, 78 } 79 80 var buffer bytes.Buffer 81 assert.NoError(t, DeepMarshalJSON(&buffer, startMsg)) 82 83 newMsg := &testprotos.SimpleMsg{} 84 assert.NoError(t, DeepUnmarshalJSON(bytes.NewReader(buffer.Bytes()), newMsg)) 85 86 assert.Equal(t, startMsg.MapField, newMsg.MapField) 87 assert.Equal(t, startMsg.SliceField, newMsg.SliceField) 88 assert.Equal(t, fromPrefix+toPrefix+startMsg.PlainField, newMsg.PlainField) 89 90 tppff.fromError = fmt.Errorf("Failing from intentionally") 91 assert.Error(t, DeepUnmarshalJSON(bytes.NewReader(buffer.Bytes()), newMsg)) 92 93 tppff.toError = fmt.Errorf("Failing to intentionally") 94 assert.Error(t, DeepMarshalJSON(&buffer, startMsg)) 95 } 96 97 type testProtoMapFieldFactory struct { 98 fromPrefix string 99 toPrefix string 100 fromError error 101 toError error 102 } 103 104 func (tpff *testProtoMapFieldFactory) Handles(msg proto.Message, fieldName string, fieldType reflect.Type, fieldValue reflect.Value) bool { 105 return fieldName == "map_field" 106 } 107 108 func (tpff *testProtoMapFieldFactory) NewProtoField(msg proto.Message, fieldName string, fieldType reflect.Type, fieldValue reflect.Value) (protoField, error) { 109 return &mapField{ 110 baseField: baseField{ 111 msg: msg, 112 name: fieldName, 113 fType: reflect.TypeOf(""), 114 vType: fieldType, 115 value: fieldValue, 116 }, 117 populateFrom: func(key string, source interface{}, destType reflect.Type) (reflect.Value, error) { 118 sourceAsString := source.(string) 119 return reflect.ValueOf(tpff.fromPrefix + key + sourceAsString), tpff.fromError 120 }, 121 populateTo: func(key string, source reflect.Value) (interface{}, error) { 122 return tpff.toPrefix + key + source.Interface().(string), tpff.toError 123 }, 124 }, nil 125 } 126 127 func TestSimpleMsgMapField(t *testing.T) { 128 fromPrefix := "from" 129 toPrefix := "to" 130 tpmff := &testProtoMapFieldFactory{ 131 fromPrefix: fromPrefix, 132 toPrefix: toPrefix, 133 } 134 fieldFactories = []protoFieldFactory{tpmff} 135 136 key := "foo" 137 value := "bar" 138 startMsg := &testprotos.SimpleMsg{ 139 PlainField: "1", 140 MapField: map[string]string{key: value}, 141 SliceField: []string{"a", "b"}, 142 } 143 144 var buffer bytes.Buffer 145 assert.NoError(t, DeepMarshalJSON(&buffer, startMsg)) 146 147 newMsg := &testprotos.SimpleMsg{} 148 assert.NoError(t, DeepUnmarshalJSON(bytes.NewReader(buffer.Bytes()), newMsg)) 149 150 assert.Equal(t, startMsg.PlainField, newMsg.PlainField) 151 assert.Equal(t, startMsg.SliceField, newMsg.SliceField) 152 assert.Equal(t, fromPrefix+key+toPrefix+key+startMsg.MapField[key], newMsg.MapField[key]) 153 154 tpmff.fromError = fmt.Errorf("Failing from intentionally") 155 assert.Error(t, DeepUnmarshalJSON(bytes.NewReader(buffer.Bytes()), newMsg)) 156 157 tpmff.toError = fmt.Errorf("Failing to intentionally") 158 assert.Error(t, DeepMarshalJSON(&buffer, startMsg)) 159 } 160 161 type testProtoSliceFieldFactory struct { 162 fromPrefix string 163 toPrefix string 164 fromError error 165 toError error 166 } 167 168 func (tpff *testProtoSliceFieldFactory) Handles(msg proto.Message, fieldName string, fieldType reflect.Type, fieldValue reflect.Value) bool { 169 return fieldName == "slice_field" 170 } 171 172 func (tpff *testProtoSliceFieldFactory) NewProtoField(msg proto.Message, fieldName string, fieldType reflect.Type, fieldValue reflect.Value) (protoField, error) { 173 return &sliceField{ 174 baseField: baseField{ 175 msg: msg, 176 name: fieldName, 177 fType: reflect.TypeOf(""), 178 vType: fieldType, 179 value: fieldValue, 180 }, 181 populateFrom: func(index int, source interface{}, destType reflect.Type) (reflect.Value, error) { 182 sourceAsString := source.(string) 183 return reflect.ValueOf(tpff.fromPrefix + fmt.Sprintf("%d", index) + sourceAsString), tpff.fromError 184 }, 185 populateTo: func(index int, source reflect.Value) (interface{}, error) { 186 return tpff.toPrefix + fmt.Sprintf("%d", index) + source.Interface().(string), tpff.toError 187 }, 188 }, nil 189 } 190 191 func TestSimpleMsgSliceField(t *testing.T) { 192 fromPrefix := "from" 193 toPrefix := "to" 194 tpsff := &testProtoSliceFieldFactory{ 195 fromPrefix: fromPrefix, 196 toPrefix: toPrefix, 197 } 198 fieldFactories = []protoFieldFactory{tpsff} 199 200 value := "foo" 201 startMsg := &testprotos.SimpleMsg{ 202 PlainField: "1", 203 MapField: map[string]string{"a": "b"}, 204 SliceField: []string{value}, 205 } 206 207 var buffer bytes.Buffer 208 assert.NoError(t, DeepMarshalJSON(&buffer, startMsg)) 209 210 newMsg := &testprotos.SimpleMsg{} 211 assert.NoError(t, DeepUnmarshalJSON(bytes.NewReader(buffer.Bytes()), newMsg)) 212 213 assert.Equal(t, startMsg.PlainField, newMsg.PlainField) 214 assert.Equal(t, startMsg.MapField, newMsg.MapField) 215 assert.Equal(t, fromPrefix+"0"+toPrefix+"0"+startMsg.SliceField[0], newMsg.SliceField[0]) 216 217 tpsff.fromError = fmt.Errorf("Failing from intentionally") 218 assert.Error(t, DeepUnmarshalJSON(bytes.NewReader(buffer.Bytes()), newMsg)) 219 220 tpsff.toError = fmt.Errorf("Failing to intentionally") 221 assert.Error(t, DeepMarshalJSON(&buffer, startMsg)) 222 } 223 224 type testProtoFailFactory struct{} 225 226 func (tpff testProtoFailFactory) Handles(msg proto.Message, fieldName string, fieldType reflect.Type, fieldValue reflect.Value) bool { 227 return true 228 } 229 230 func (tpff testProtoFailFactory) NewProtoField(msg proto.Message, fieldName string, fieldType reflect.Type, fieldValue reflect.Value) (protoField, error) { 231 return nil, fmt.Errorf("Intentionally failing") 232 } 233 234 func TestFailFactory(t *testing.T) { 235 fieldFactories = []protoFieldFactory{&testProtoFailFactory{}} 236 237 var buffer bytes.Buffer 238 assert.Error(t, DeepMarshalJSON(&buffer, &testprotos.SimpleMsg{})) 239 } 240 241 func TestJSONUnmarshalMaxUint32(t *testing.T) { 242 fieldName := "numField" 243 jsonString := fmt.Sprintf("{\"%s\":%d}", fieldName, math.MaxUint32) 244 m, err := jsonToMap([]byte(jsonString)) 245 assert.NoError(t, err) 246 assert.IsType(t, json.Number(""), m[fieldName]) 247 }