github.com/cloudwego/kitex@v0.9.0/pkg/utils/json_test.go (about)

     1  /*
     2   * Copyright 2021 CloudWeGo Authors
     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 utils
    18  
    19  import (
    20  	"encoding/json"
    21  	"testing"
    22  
    23  	jsoniter "github.com/json-iterator/go"
    24  
    25  	"github.com/cloudwego/kitex/internal/test"
    26  )
    27  
    28  var jsoni = jsoniter.ConfigCompatibleWithStandardLibrary
    29  
    30  func BenchmarkMap2JSONStr(b *testing.B) {
    31  	mapInfo := prepareMap()
    32  	b.ReportAllocs()
    33  	b.ResetTimer()
    34  	for i := 0; i < b.N; i++ {
    35  		Map2JSONStr(mapInfo)
    36  	}
    37  }
    38  
    39  func BenchmarkJSONStr2Map(b *testing.B) {
    40  	mapInfo := prepareMap()
    41  	jsonRet, _ := jsoni.MarshalToString(mapInfo)
    42  	b.ReportAllocs()
    43  	b.ResetTimer()
    44  	for i := 0; i < b.N; i++ {
    45  		JSONStr2Map(jsonRet)
    46  	}
    47  }
    48  
    49  func BenchmarkJSONMarshal(b *testing.B) {
    50  	mapInfo := prepareMap()
    51  	b.ReportAllocs()
    52  	b.ResetTimer()
    53  	for i := 0; i < b.N; i++ {
    54  		jsonMarshal(mapInfo)
    55  	}
    56  }
    57  
    58  func BenchmarkJSONUnmarshal(b *testing.B) {
    59  	mapInfo := prepareMap()
    60  	jsonRet, _ := jsoni.MarshalToString(mapInfo)
    61  	b.ReportAllocs()
    62  	b.ResetTimer()
    63  	for i := 0; i < b.N; i++ {
    64  		var map1 map[string]string
    65  		json.Unmarshal([]byte(jsonRet), &map1)
    66  	}
    67  }
    68  
    69  func BenchmarkJSONIterMarshal(b *testing.B) {
    70  	mapInfo := prepareMap()
    71  	b.ReportAllocs()
    72  	b.ResetTimer()
    73  	for i := 0; i < b.N; i++ {
    74  		jsoni.MarshalToString(mapInfo)
    75  	}
    76  }
    77  
    78  func BenchmarkJSONIterUnmarshal(b *testing.B) {
    79  	mapInfo := prepareMap()
    80  	jsonRet, _ := Map2JSONStr(mapInfo)
    81  	b.ReportAllocs()
    82  	b.ResetTimer()
    83  	for i := 0; i < b.N; i++ {
    84  		var map1 map[string]string
    85  		jsoni.UnmarshalFromString(jsonRet, &map1)
    86  	}
    87  }
    88  
    89  // TestMap2JSONStr test convert map to json string
    90  func TestMap2JSONStr(t *testing.T) {
    91  	mapInfo := prepareMap()
    92  
    93  	jsonRet1, err := Map2JSONStr(mapInfo)
    94  	test.Assert(t, err == nil)
    95  	jsonRet2, _ := json.Marshal(mapInfo)
    96  
    97  	// 用Unmarshal解序列化两种方式的jsonStr
    98  	var map1 map[string]string
    99  	json.Unmarshal([]byte(jsonRet1), &map1)
   100  	var map2 map[string]string
   101  	json.Unmarshal(jsonRet2, &map2)
   102  
   103  	test.Assert(t, len(map1) == len(map2))
   104  	for k := range map1 {
   105  		test.Assert(t, map1[k] == map2[k])
   106  	}
   107  
   108  	mapInfo = nil
   109  	jsonRetNil, err := Map2JSONStr(mapInfo)
   110  	test.Assert(t, err == nil)
   111  	test.Assert(t, jsonRetNil == "{}")
   112  }
   113  
   114  // TestJSONStr2Map test convert json string to map
   115  func TestJSONStr2Map(t *testing.T) {
   116  	mapInfo := prepareMap()
   117  	jsonRet, _ := json.Marshal(mapInfo)
   118  	mapRet, err := JSONStr2Map(string(jsonRet))
   119  	test.Assert(t, err == nil)
   120  
   121  	test.Assert(t, len(mapInfo) == len(mapRet))
   122  	for k := range mapInfo {
   123  		test.Assert(t, mapInfo[k] == mapRet[k])
   124  	}
   125  
   126  	str := "null"
   127  	ret, err := JSONStr2Map(str)
   128  	test.Assert(t, ret == nil)
   129  	test.Assert(t, err == nil)
   130  	str = "nUll"
   131  	ret, err = JSONStr2Map(str)
   132  	test.Assert(t, ret == nil)
   133  	test.Assert(t, err != nil)
   134  	str = "nuLL"
   135  	ret, err = JSONStr2Map(str)
   136  	test.Assert(t, ret == nil)
   137  	test.Assert(t, err != nil)
   138  	str = "nulL"
   139  	ret, err = JSONStr2Map(str)
   140  	test.Assert(t, ret == nil)
   141  	test.Assert(t, err != nil)
   142  
   143  	str = "{}"
   144  	ret, err = JSONStr2Map(str)
   145  	test.Assert(t, ret == nil)
   146  	test.Assert(t, err == nil)
   147  
   148  	str = "{"
   149  	ret, err = JSONStr2Map(str)
   150  	test.Assert(t, ret == nil)
   151  	test.Assert(t, err != nil)
   152  
   153  	unicodeStr := `{"\u4f60\u597d": "\u5468\u6770\u4f26"}`
   154  	mapRet, err = JSONStr2Map(unicodeStr)
   155  	test.Assert(t, err == nil)
   156  	test.Assert(t, mapRet["你好"] == "周杰伦")
   157  
   158  	unicodeMixedStr := `{"aaa\u4f60\u597daaa": ":\\\u5468\u6770\u4f26"  ,  "加油 \u52a0\u6cb9" : "Come on \u52a0\u6cb9"}`
   159  	mapRet, err = JSONStr2Map(unicodeMixedStr)
   160  	test.Assert(t, err == nil)
   161  	test.Assert(t, mapRet["aaa你好aaa"] == ":\\周杰伦")
   162  	test.Assert(t, mapRet["加油 加油"] == "Come on 加油")
   163  
   164  	unicodeMixedStr = `{"aaa\u4F60\u597Daaa": "\u5468\u6770\u4f26"}`
   165  	mapRet, err = JSONStr2Map(unicodeMixedStr)
   166  	test.Assert(t, err == nil)
   167  	test.Assert(t, mapRet["aaa你好aaa"] == "周杰伦")
   168  
   169  	illegalUnicodeStr := `{"aaa\u4z60\u597daaa": "加油"}`
   170  	illegalUnicodeMapRet, err := JSONStr2Map(illegalUnicodeStr)
   171  	test.Assert(t, err != nil)
   172  	test.Assert(t, len(illegalUnicodeMapRet) == 0)
   173  
   174  	surrogateUnicodeStr := `{"\u4F60\u597D": "\uDFFF\uD800"}`
   175  	surrogateUnicodeMapRet, err := JSONStr2Map(surrogateUnicodeStr)
   176  	test.Assert(t, err == nil)
   177  	test.Assert(t, surrogateUnicodeMapRet != nil)
   178  
   179  	illegalEscapeCharStr := `{"\x4F60\x597D": "\uDFqwdFF\uD800"}`
   180  	illegalEscapeCharMapRet, err := JSONStr2Map(illegalEscapeCharStr)
   181  	test.Assert(t, err != nil)
   182  	test.Assert(t, len(illegalEscapeCharMapRet) == 0)
   183  }
   184  
   185  // TestJSONUtil compare return between encoding/json, json-iterator and json.go
   186  func TestJSONUtil(t *testing.T) {
   187  	mapInfo := prepareMap()
   188  	jsonRet1, _ := json.Marshal(mapInfo)
   189  	jsonRet2, _ := jsoni.MarshalToString(mapInfo)
   190  	jsonRet, _ := Map2JSONStr(mapInfo)
   191  
   192  	var map1 map[string]string
   193  	json.Unmarshal(jsonRet1, &map1)
   194  	var map2 map[string]string
   195  	json.Unmarshal([]byte(jsonRet2), &map2)
   196  	var map3 map[string]string
   197  	json.Unmarshal([]byte(jsonRet), &map3)
   198  
   199  	test.Assert(t, len(map1) == len(map3))
   200  	test.Assert(t, len(map2) == len(map3))
   201  	for k := range map1 {
   202  		test.Assert(t, map2[k] == map3[k])
   203  	}
   204  
   205  	mapRetIter := make(map[string]string)
   206  	jsoni.UnmarshalFromString(string(jsonRet1), &mapRetIter)
   207  	mapRet, err := JSONStr2Map(string(jsonRet1))
   208  	test.Assert(t, err == nil)
   209  
   210  	test.Assert(t, len(mapRet) == len(mapRetIter))
   211  	test.Assert(t, len(mapRet) == len(map1))
   212  
   213  	for k := range map1 {
   214  		test.Assert(t, mapRet[k] == mapRetIter[k])
   215  	}
   216  }
   217  
   218  func prepareMap() map[string]string {
   219  	mapInfo := make(map[string]string)
   220  	mapInfo["a"] = "a"
   221  	mapInfo["bb"] = "bb"
   222  	mapInfo["ccc"] = "ccc"
   223  	mapInfo["env"] = "test"
   224  	mapInfo["destService"] = "kite.server"
   225  	mapInfo["remoteIP"] = "10.1.2.100"
   226  	mapInfo["hello"] = "hello"
   227  	mapInfo["fongojannfsoaigsang ojosaf"] = "fsdaufsdjagnji91nngnajjmfsaf"
   228  	mapInfo["公司"] = "字节"
   229  
   230  	mapInfo["a\""] = "b"
   231  	mapInfo["c\""] = "\"d"
   232  	mapInfo["e\"ee"] = "ff\"f"
   233  	mapInfo["g:g,g"] = "h,h:hh"
   234  	mapInfo["i:\a\"i"] = "g\"g:g"
   235  	mapInfo["k:\\k\":\"\\\"k"] = "l\\\"l:l"
   236  	mapInfo["m, m\":"] = "n	n\":\"n"
   237  	mapInfo["m, &m\":"] = "n<!	>n\":\"n"
   238  	mapInfo[`{"aaa\u4f60\u597daaa": ":\\\u5468\u6770\u4f26"  ,  "加油 \u52a0\u6cb9" : "Come on \u52a0\u6cb9"}`] = `{"aaa\u4f60\u597daaa": ":\\\u5468\u6770\u4f26"  ,  "加油 \u52a0\u6cb9" : "Come on \u52a0\u6cb9"}`
   239  	return mapInfo
   240  }
   241  
   242  func jsonMarshal(userExtraMap map[string]string) (string, error) {
   243  	ret, err := json.Marshal(userExtraMap)
   244  	return string(ret), err
   245  }