github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zjson/get_test.go (about) 1 package zjson 2 3 import ( 4 "strings" 5 "testing" 6 "time" 7 8 "github.com/sohaha/zlsgo" 9 "github.com/sohaha/zlsgo/zstring" 10 "github.com/sohaha/zlsgo/ztype" 11 ) 12 13 type Demo struct { 14 Quality string `json:"quality"` 15 User struct { 16 Name string `json:"name"` 17 } `json:"user"` 18 Children []string `json:"children"` 19 Friends []struct { 20 Name string `json:"name"` 21 } `json:"friends"` 22 I int `json:"i"` 23 F float64 24 } 25 26 type SS struct { 27 Name string `json:"name"` 28 Gg GG `json:"g"` 29 To []string `json:"t"` 30 IDs []AA `json:"ids"` 31 Property struct { 32 Name string `json:"n"` 33 Key float64 34 } `json:"p"` 35 Abc int 36 ID int `json:"id"` 37 Pid uint 38 To2 int `json:"t2"` 39 } 40 41 type GG struct { 42 Info string 43 P []AA `json:"p"` 44 } 45 46 type AA struct { 47 Name string 48 Gg GG `json:"g"` 49 ID int `json:"id"` 50 } 51 52 func TestGet2(t *testing.T) { 53 Parse(`{"a":null}`).Get("a").ForEach(func(key, value *Res) bool { 54 t.Log(key, value) 55 t.Fail() 56 return true 57 }) 58 get := Parse(`{"a":{"b":"a123",}`).Get("a") 59 get.ForEach(func(key, value *Res) bool { 60 t.Log(key, value) 61 return true 62 }) 63 t.Log(get.str) 64 t.Log(get.raw) 65 t.Log(get.Get("b")) 66 } 67 68 func TestGet(t *testing.T) { 69 tt := zlsgo.NewTest(t) 70 SetModifiersState(true) 71 quality := Get(demo, "quality") 72 tt.EqualExit("highLevel", quality.String()) 73 user := Get(demo, "user") 74 name := user.Get("name").String() 75 other := Get(demo, "other") 76 t.Log(other.Array(), other.Raw()) 77 tt.EqualExit("暴龙兽", name) 78 tt.EqualExit(name, string(user.Get("name").Bytes())) 79 tt.EqualExit("-999", Get(demo, "ii").String()) 80 tt.EqualExit(666, Get(demo, "other.1").Int()) 81 tt.Log(Get(demo, "other.1").typ.String()) 82 tt.EqualExit(0, Get(demo, "other.2").Int()) 83 tt.Log(Get(demo, "other.2").typ.String()) 84 tt.EqualExit(0, Get(demo, "bool").Int()) 85 tt.Log(Get(demo, "bool").typ.String()) 86 tt.EqualExit(1, Get(demo, "boolTrue").Int()) 87 tt.EqualExit(0, Get(demo, "time").Int()) 88 _ = Get(demo, "time").typ.String() 89 _ = Get(demo, "timeNull").typ.String() 90 tt.EqualExit(1.8, Get(demo, "other.2").Float()) 91 tt.EqualExit(66.6, Get(demo, "index\\.key").Float()) 92 93 tt.EqualExit(uint(666), Get(demo, "other.1").Uint()) 94 tt.EqualExit(uint(0), Get(demo, "time").Uint()) 95 tt.EqualExit(uint(1), Get(demo, "f").Uint()) 96 tt.EqualExit(uint(0), Get(demo, "user").Uint()) 97 tt.EqualExit(uint(1), Get(demo, "boolTrue").Uint()) 98 99 tt.EqualExit("666", Get(demo, "other.1").String()) 100 tt.EqualExit(false, Get(demo, "bool").Bool()) 101 _ = Get(demo, "boolTrue").typ.String() 102 tt.EqualExit("false", Get(demo, "bool").String()) 103 tt.EqualExit(true, Get(demo, "boolTrue").Bool()) 104 tt.EqualExit(false, Get(demo, "boolTrueNot").Bool()) 105 tt.EqualExit("true", Get(demo, "boolTrue").String()) 106 t.Log(Get(demo, "time").Bool(), Get(demo, "time").String()) 107 tt.EqualExit(false, Get(demo, "time").Bool()) 108 tt.EqualExit(true, Get(demo, "i").Bool()) 109 timeStr := Get(demo, "time").String() 110 tt.EqualExit("2019-09-10 13:48:22", timeStr) 111 loc, _ := time.LoadLocation("Local") 112 ttime, _ := time.ParseInLocation("2006-01-02 15:04:05", timeStr, loc) 113 tt.EqualExit(ttime, Get(demo, "time").Time()) 114 tt.EqualExit(true, Get(demo, "user").IsObject()) 115 tt.EqualExit(true, Get(demo, "user").IsObject()) 116 tt.EqualExit(true, Get(demo, "user").Exists()) 117 tt.EqualExit("暴龙兽", Get(demo, "user").Map().Get("name").String()) 118 tt.EqualExit("天使兽", Get(demo, "friends").Maps().First().Get("name").String()) 119 tt.EqualExit(Get(demo, "friends").Maps().First().Get("name").String(), Get(demo, "friends").Maps().Index(0).Get("name").String()) 120 tt.EqualExit(true, other.IsArray()) 121 tt.EqualExit(Get(demo, "friends.1").String(), Get(demo, "friends").Get("#(name=天女兽)").String()) 122 tt.EqualExit(2, Get(demo, "friends.#").Int()) 123 tt.EqualExit("天女兽", Get(demo, "friends.#(age>1).name").String()) 124 tt.EqualExit("天女兽", Get(demo, "f?iends.1.name").String()) 125 tt.EqualExit("[\"天女兽\"]", Get(demo, "[friends.1.name]").String()) 126 tt.EqualExit(false, Valid("{{}")) 127 tt.EqualExit(true, Valid(demo)) 128 tt.EqualExit("阿古兽", Get(demo, "children").SliceString()[0]) 129 tt.EqualExit(0, Get(demo, "children").SliceInt()[0]) 130 131 ForEachLine(demo+demo, func(line *Res) bool { 132 return true 133 }) 134 135 maps := Get(demo, "user").Value().(map[string]interface{}) 136 for key, value := range maps { 137 tt.EqualExit("name", key) 138 tt.EqualExit("暴龙兽", value.(string)) 139 } 140 141 parseData := Parse(demo) 142 t.Log(parseData.MapRes()) 143 t.Log(parseData.MapKeys("children")) 144 145 other.ForEach(func(key, value *Res) bool { 146 return true 147 }) 148 149 Parse(`{"a":null}`).Get("a").ForEach(func(key, value *Res) bool { 150 t.Log(key, value) 151 t.Fail() 152 return true 153 }) 154 Parse(`{"a":"a123"}`).Get("a").ForEach(func(key, value *Res) bool { 155 t.Log(key, value) 156 return true 157 }) 158 159 byteData := zstring.String2Bytes(demo) 160 tt.EqualTrue(ValidBytes(byteData)) 161 tt.EqualExit("暴龙兽", GetBytes(byteData, "user.name").String()) 162 163 resData := GetMultiple(demo, "user.name", "f?iends.1.name") 164 _ = GetMultipleBytes(byteData, "user.name", "f?iends.1.name") 165 tt.EqualExit("暴龙兽", resData[0].String()) 166 tt.EqualExit("天女兽", resData[1].String()) 167 168 modifierFn := func(json, arg string) string { 169 if arg == "upper" { 170 return strings.ToUpper(json) 171 } 172 if arg == "lower" { 173 return strings.ToLower(json) 174 } 175 return json 176 } 177 AddModifier("case", modifierFn) 178 tt.EqualExit(true, ModifierExists("case")) 179 tt.EqualExit("HIGHLEVEL", Get(demo, "quality|@case:upper|@reverse").String()) 180 t.Log(Get(demo, "friends").String()) 181 t.Log(Get(demo, "friends|@reverse|@case:upper").String()) 182 t.Log(Get(demo, "friends|@format:{\"indent\":\"--\"}").String()) 183 184 type Demo struct { 185 Quality string `json:"quality"` 186 I int `json:"i"` 187 } 188 var demoData Demo 189 demoJson := Ugly(zstring.String2Bytes(demo)) 190 err := Unmarshal(demoJson, &demoData) 191 t.Log(err, demoData, string(demoJson)) 192 193 err = Unmarshal(zstring.String2Bytes(demo), &demoData) 194 tt.EqualExit(true, err == nil) 195 tt.Log(err, demoData) 196 197 err = Unmarshal(demo, &demoData) 198 tt.EqualExit(true, err == nil) 199 tt.Log(err, demoData) 200 201 err = Unmarshal("demo", &demoData) 202 tt.EqualExit(true, err != nil) 203 tt.Log(err, demoData) 204 205 var i struct { 206 I int `json:"i"` 207 } 208 _ = parseData.Unmarshal(&i) 209 tt.Log(i) 210 tt.Log(Get(demo, "friends").typ.String()) 211 tt.Log(parseData.Get("@reverse").String()) 212 } 213 214 func TestForEach(t *testing.T) { 215 tt := zlsgo.NewTest(t) 216 arr := Parse(`{"names":[{"name":1},{"name":2}],"values":[3,4]}`) 217 arr.ForEach(func(key, value *Res) bool { 218 tt.Log("key:", key, "value:", value.String()) 219 return true 220 }) 221 222 i := 0 223 arr.Get("names").ForEach(func(key, value *Res) bool { 224 tt.Log("key:", key.Int(), "value:", value.String()) 225 tt.Equal(i, key.Int()) 226 i++ 227 return true 228 }) 229 230 Parse(`[{"fen": 63.12, "date": "2023-08-24"}]`).ForEach(func(key, value *Res) bool { 231 tt.Log(key, value) 232 tt.Equal(63.12, value.Get("fen").Float()) 233 return true 234 }) 235 236 } 237 238 func TestUnmarshal(t *testing.T) { 239 tt := zlsgo.NewTest(t) 240 json := `{"id":666,"Pid":100,"name":"HelloWorld","g":{"Info":"基础"},"ids":[{"id":1,"Name":"用户1","g":{"Info":"详情","p":[{"Name":"n1","id":1},{"id":2}]}}]}` 241 var s SS 242 err := Unmarshal(json, &s) 243 tt.NoError(err) 244 tt.Logf("%+v", s) 245 tt.Equal("用户1", s.IDs[0].Name) 246 tt.Equal("n1", s.IDs[0].Gg.P[0].Name) 247 } 248 249 func TestEditJson(t *testing.T) { 250 tt := zlsgo.NewTest(t) 251 j := Parse(demo) 252 253 name := j.Get("user.name").String() 254 _ = j.Delete("user.name") 255 nName := j.Get("user.name").String() 256 tt.Equal("", nName) 257 tt.Equal("暴龙兽", name) 258 259 c1 := j.Get("children.0").String() 260 _ = j.Delete("children.0") 261 _ = j.Delete("children.0") 262 nc1 := j.Get("children.0").String() 263 tt.Equal("阿古兽", c1) 264 tt.Equal("机器暴龙兽", nc1) 265 266 _ = j.Set("new_path.0", "仙人掌兽") 267 _ = j.Set("new_path.1", "花仙兽") 268 269 t.Log(j.Get("friends.0").Map()) 270 271 t.Log(string(Ugly([]byte(j.String())))) 272 } 273 274 func TestGetFormat(t *testing.T) { 275 SetModifiersState(true) 276 t.Log(Get(demo, "friends|@format:{\"indent\":\"--\"}").String()) 277 } 278 279 func TestModifiers(t *testing.T) { 280 SetModifiersState(true) 281 t.Log(Get(demo, "friends").String()) 282 t.Log(Get(demo, "friends|@reverse").String()) 283 t.Log(Get(demo, "friends|@ugly").String()) 284 t.Log(Get(demo, "friends|@format").String()) 285 } 286 287 func TestType(t *testing.T) { 288 tt := zlsgo.NewTest(t) 289 tt.EqualExit(float64(1), Get(`{"a":true}`, "a").Float()) 290 tt.EqualExit(float64(0), Get(`{"a":false}`, "a").Float()) 291 tt.EqualExit(ztype.Map{}, Get(`{}`, "a").Map()) 292 tt.EqualExit(ztype.Maps{}, Get(`{}`, "a").Maps()) 293 tt.EqualExit([]*Res{}, Get(`{}`, "a").Array()) 294 } 295 296 func BenchmarkGet(b *testing.B) { 297 b.ResetTimer() 298 for i := 0; i < b.N; i++ { 299 _ = Get(demo, "i") 300 } 301 } 302 303 func BenchmarkGetBytes(b *testing.B) { 304 demoByte := []byte(demo) 305 b.ResetTimer() 306 for i := 0; i < b.N; i++ { 307 _ = GetBytes(demoByte, "i") 308 } 309 } 310 311 func BenchmarkGetBig(b *testing.B) { 312 json := getBigJSON() 313 b.ResetTimer() 314 for i := 0; i < b.N; i++ { 315 _ = Get(json, "i") 316 } 317 } 318 319 func BenchmarkGetBigBytes(b *testing.B) { 320 json := zstring.String2Bytes(getBigJSON()) 321 b.ResetTimer() 322 for i := 0; i < b.N; i++ { 323 _ = GetBytes(json, "i") 324 } 325 }