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 }