github.com/dfklegend/cell2/utils@v0.0.0-20240402033734-a0a9f3d9335d/serialize/json/json_test.go (about)

     1  // Copyright (c) nano Author and TFG Co. All Rights Reserved.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in all
    11  // copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    19  // SOFTWARE.
    20  
    21  package json
    22  
    23  import (
    24  	"encoding/json"
    25  	"log"
    26  	"math"
    27  	"testing"
    28  
    29  	"github.com/stretchr/testify/assert"
    30  
    31  	"github.com/dfklegend/cell2/utils/serialize/proto/msgs"
    32  )
    33  
    34  func TestNewSerializer(t *testing.T) {
    35  	t.Parallel()
    36  
    37  	serializer := NewSerializer()
    38  
    39  	assert.NotNil(t, serializer)
    40  }
    41  
    42  func TestMarshal(t *testing.T) {
    43  	t.Parallel()
    44  
    45  	type MyStruct struct {
    46  		Str    string
    47  		Number float64
    48  	}
    49  	var marshalTables = map[string]struct {
    50  		raw       interface{}
    51  		marshaled []byte
    52  		errType   interface{}
    53  	}{
    54  		"test_ok": {
    55  			&MyStruct{Str: "hello", Number: 42},
    56  			[]byte(`{"Str":"hello","Number":42}`),
    57  			nil,
    58  		},
    59  		"test_nok": {
    60  			&MyStruct{Number: math.Inf(1)},
    61  			nil,
    62  			&json.UnsupportedValueError{},
    63  		},
    64  	}
    65  	serializer := NewSerializer()
    66  
    67  	for name, table := range marshalTables {
    68  		t.Run(name, func(t *testing.T) {
    69  			result, err := serializer.Marshal(table.raw)
    70  
    71  			assert.Equal(t, table.marshaled, result)
    72  			if table.errType == nil {
    73  				assert.NoError(t, err)
    74  			} else {
    75  				assert.IsType(t, table.errType, err)
    76  			}
    77  		})
    78  	}
    79  }
    80  
    81  func TestUnmarshal(t *testing.T) {
    82  	t.Parallel()
    83  
    84  	type MyStruct struct {
    85  		Str    string
    86  		Number int
    87  	}
    88  	var unmarshalTables = map[string]struct {
    89  		data        []byte
    90  		unmarshaled *MyStruct
    91  		errType     interface{}
    92  	}{
    93  		"test_ok": {
    94  			[]byte(`{"Str":"hello","Number":42}`),
    95  			&MyStruct{Str: "hello", Number: 42},
    96  			nil,
    97  		},
    98  		"test_nok": {
    99  			[]byte(`invalid`),
   100  			nil,
   101  			&json.SyntaxError{},
   102  		},
   103  	}
   104  	serializer := NewSerializer()
   105  
   106  	for name, table := range unmarshalTables {
   107  		t.Run(name, func(t *testing.T) {
   108  			var result MyStruct
   109  			err := serializer.Unmarshal(table.data, &result)
   110  			if table.errType == nil {
   111  				assert.NoError(t, err)
   112  				assert.Equal(t, table.unmarshaled, &result)
   113  			} else {
   114  				assert.Empty(t, &result)
   115  				assert.IsType(t, table.errType, err)
   116  			}
   117  		})
   118  	}
   119  }
   120  
   121  type ServiceRequest struct {
   122  	Sender string
   123  	ReqId  int32
   124  	Type   string
   125  }
   126  
   127  type ServiceRequest1 struct {
   128  	ReqId  int32
   129  	Sender string
   130  	Type   string
   131  }
   132  
   133  type ServiceRequest2 struct {
   134  	ReqId  string
   135  	Sender string
   136  	Type   int32
   137  }
   138  
   139  /*
   140  	测试数据结构变化, json序列化接口的影响
   141  	名字一致,读取正确
   142  */
   143  func TestMismatch(t *testing.T) {
   144  	in := &ServiceRequest{
   145  		Sender: "someone",
   146  		ReqId:  99,
   147  		Type:   "type",
   148  	}
   149  
   150  	log.Printf("origin data: %+v\n", in)
   151  
   152  	serializer := NewSerializer()
   153  	bytes, _ := serializer.Marshal(in)
   154  
   155  	r1 := &ServiceRequest1{}
   156  	serializer.Unmarshal(bytes, r1)
   157  	log.Printf("%+v\n", r1)
   158  
   159  	assert.Equal(t, "someone", r1.Sender)
   160  	assert.Equal(t, "type", r1.Type)
   161  
   162  	r2 := &ServiceRequest2{}
   163  	r2.ReqId = "100"
   164  	serializer.Unmarshal(bytes, r2)
   165  	log.Printf("%+v\n", r2)
   166  
   167  	// 类型不一致,会被忽略
   168  	assert.Equal(t, "100", r2.ReqId)
   169  	assert.Equal(t, int32(0), r2.Type)
   170  }
   171  
   172  // 223 ns/op
   173  func BenchmarkMarshal(b *testing.B) {
   174  	in := &msgs.ServiceRequest{
   175  		Sender: "someone",
   176  		ReqId:  99,
   177  		Type:   "type",
   178  	}
   179  
   180  	serializer := NewSerializer()
   181  	for i := 0; i < b.N; i++ {
   182  		serializer.Marshal(in)
   183  	}
   184  }