JSON.uts 15.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
import { describe, test, expect, expectNumber, Result } from './tests.uts'



type UserJSON = {
  id : string;
  name : string | null;
}

type PersonJSON = {
  /**
  * @JSON_FIELD "a+b"
  */
  a_b : string;
  /**
  * @JSON_FIELD "a-b"
  */
  a_b_ : number;
  /**
  * @JSON_FIELD "class"
  */
  _class : boolean;
}


26 27
function countOccurrences(str : string, substr : string) : number {

28 29 30 31
  let count = 0
  let position = 0

  while (true) {
32 33 34 35
    position = str.indexOf(substr, position)
    if (position == -1) break
    count++
    position += substr.length
36 37 38 39
  }

  return count;
}
40

41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
class A1 implements IJsonStringify{
  override toJSON():any|null{
  	let jsonRet = {
  		'name': "zhangsan",
  		'age': 12,
  	}
  	return jsonRet
  }
}

class A2 implements IJsonStringify{
  override toJSON():any|null{
  	return 2
  }
}

class A3 implements IJsonStringify{
  override toJSON():any|null{
  	return "json"
  }
}

class A4 implements IJsonStringify{
  override toJSON():any|null{
  	return null
  }
}

class A5 implements IJsonStringify{
  override toJSON():any|null{
  	return new A1()
  }
}

class A6 implements IJsonStringify{
  override toJSON():any|null{
  	return new A5()
  }
}

81 82 83

export function testJSON() : Result {
  return describe("JSON", () => {
84 85 86 87 88 89 90 91 92 93
    
    test('custom-stringify', () => {
      expect(JSON.stringify(new A1()).length).toEqual(28)
      expect(JSON.stringify(new A2())).toEqual("2")
      expect(JSON.stringify(new A3())).toEqual('"json"')
      expect(JSON.stringify(new A4())).toEqual('null')
      expect(JSON.stringify(new A5()).length).toEqual(28)
      expect(JSON.stringify(new A6()).length).toEqual(28)
    })
    
94
    test('parse', () => {
95
      // #TEST JSON.parse_tip,JSON.parse
96 97
      const json = `{"result":true, "count":42}`;
      const obj = JSON.parse(json) as UTSJSONObject;
98 99 100 101 102 103 104 105
      console.log(obj["count"]);
      // expected output: 42

      console.log(obj["result"]);
      // expected output: true
      // #END


106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
      expect(obj["count"]).toEqual(42);
      expect(obj["result"] as boolean).toEqual(true);

      const json1 = `{
                "name": "John",
                "age": 30,
                "city": "New York"
              }`;
      const obj1 = JSON.parse(json1);
      // expect(obj1).toEqual({
      //     name: 'John',
      //     age: 30,
      //     city: 'New York',
      // });
      expect((obj1! as UTSJSONObject).getString('name')).toEqual("John")

122
      // #TEST JSON.parse_1
123 124
      const json2 = '{"string":"Hello","number":42,"boolean":true,"nullValue":null,"array":[1,2,3],"object":{"nestedKey":"nestedValue"}}';
      const obj2 = JSON.parse<UTSJSONObject>(json2)!;
125
      // #END
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
      // expect(obj2).toEqual({
      //     string: 'Hello',
      //     number: 42,
      //     boolean: true,
      //     nullValue: null,
      //     array: [1, 2, 3],
      //     object: {
      //         nestedKey: 'nestedValue',
      //     },
      // });
      expect(obj2['object']).toEqual({
        nestedKey: 'nestedValue',
      })
      expect(obj2.getString("object.nestedKey")).toEqual('nestedValue')


      let json3 = `{"id":"216776999999","name":"小王","grade":1.0,"list":[1,2,3],"address":{"province":"beijing","city":"haidian","streat":"taipingzhuang","other":2},"anyValue":[[null,null]],"obj":{"a":1,"b":false,"c":null},"customClass":{"name":"lisi","age":30},"numList":[1,2,3,null],"list2":[1,2,3,4],"dic":{"1":{"c":[null]}},"dicArr":[{"a":{"c":[null]}},{"b":{"c":1}}]}`
      let obj3 = JSON.parse(json3)! as UTSJSONObject;
      let obj3Address = obj3.getAny("address")!
      console.log(obj3Address)
      expect(obj3Address instanceof UTSJSONObject).toEqual(true)
      let obj3DicArr = obj3.getArray("dicArr")!
      let obj3DicArrFirst = obj3DicArr[0] as UTSJSONObject
      let obj3DicArrFirstA = obj3DicArrFirst['a']
      console.log(obj3DicArrFirstA instanceof UTSJSONObject)
      expect(obj3DicArrFirstA instanceof UTSJSONObject).toEqual(true)
      // 目前仅android 支持,暂不放开
      // let obj3 = JSON.parse<User>(json1);
      // console.log(obj3)

      // const json3 = '["apple","banana","cherry"]';
      // const obj3 = JSON.parse(json3)!;
      // TODO JSON.parse 后数组的类型 无法强转
      // expect(obj3).toEqual(['apple', 'banana', 'cherry']);

      // const json4 = '[1, "two", true, null, {"key": "value"}, ["nested"]]';
      // const obj4 = JSON.parse(json4)!;
      // expect(obj4).toEqual([1, 'two', true, null, { key: 'value' }, ['nested']]);

      // TODO 暂不支持多个参数
      // const json5 = '{"p": 5}';
      // const obj5 = JSON.parse(json5, function (k : string, v : number) : number {
      //     if (k === '') return v;
      //     return v * 2;
      // })!;
      // expect(obj5).toEqual({
      //     p: 10,
      // });


      expect(JSON.parse('{}')!).toEqual({});

      // TODO 不支持boolean、string,js端需抹平
      // expect(JSON.parse('true')!).toEqual(true);
      // expect(JSON.parse('"foo"')!).toEqual("foo");
      // expect(JSON.parse('null')!).toEqual(null);

      const json4 = '{"data":[{"a":"1"},{"a":2},[{"b":true},{"b":"test"}],[1, 2, 3]]}';
      const obj4 = JSON.parseObject(json4);
      expect(obj4?.getString('data[0].a')).toEqual("1")
      expect(obj4?.getNumber('data[1].a')).toEqual(2)
      expect(obj4?.getBoolean('data[2][0].b')).toEqual(true)
      expect(obj4?.getAny('data[1].a')).toEqual(2)
      expect(obj4?.getJSON('data[2][1]')).toEqual({ "b": "test" })
      expect(obj4?.getArray('data[3]')).toEqual([1, 2, 3])

    })
    test('parseObject', () => {
194
      // #TEST JSON.parseObject
195 196
      const json = `{"result":true, "count":42}`;
      const obj = JSON.parseObject(json);
197 198 199
      console.log(obj?.["count"])//42
      // #END

杜庆泉's avatar
杜庆泉 已提交
200 201
      expect(obj?.["count"]).toEqual(42);
      expect(obj?.["result"] as boolean).toEqual(true);
202 203

      expect(JSON.parseObject('{}')!).toEqual({});
204
      // #TEST JSON.parseObject_1
205 206 207 208 209
      const json1 = `{
			    "name": "John",
			    "id": "30"
			  }`;
      let obj2 = JSON.parseObject<UserJSON>(json1);
210 211
      console.log(obj2!.id) //30
      // #END
212 213 214 215 216 217 218 219 220 221 222 223 224 225
      expect(obj2!.id).toEqual("30");

      const json2 = `{
			    "id": "30"
			  }`;
      let obj3 = JSON.parseObject<UserJSON>(json2);
      expect(obj3!.id).toEqual("30");
      const json3 = `{
			    "name": "John"
			  }`;
      let obj4 = JSON.parseObject<UserJSON>(json3);
      expect(obj4).toEqual(null);
    })
    test('parseArray', () => {
226
      // #TEST JSON.parseArray
227 228
      const json1 = `[1,2,3]`;
      const array1 = JSON.parseArray(json1);
229 230
      console.log(array1)//[1, 2, 3]
      // #END
231 232 233 234 235 236 237
      expect(array1).toEqual([1, 2, 3]);

      const json2 = `[1,"hello world",3]`;
      const array2 = JSON.parseArray(json2);
      expect(array2).toEqual([1, "hello world", 3]);


杜庆泉's avatar
杜庆泉 已提交
238
      // #ifdef APP-ANDROID
239
      // #TEST JSON.parseArray_1
240 241
      const json3 = `[{"name":"John","id":"30"},{"name":"jack","id":"21"}]`;
      const array3 = JSON.parseArray<UTSJSONObject>(json3);
242 243
      console.log((array3![0])["name"])//"John"
      // #END
杜庆泉's avatar
杜庆泉 已提交
244 245
      expect((array3![0])["name"]).toEqual("John");
      // #endif
246
    })
247

248 249
    test('merge-test-1', () => {
      // #ifdef APP-ANDROID
250 251 252 253 254 255 256 257 258 259 260 261 262
      const data1 = {
        name: 'Tom1',
        age: 21
      };

      const data2 = {
        aa: {
          name: 'Tom2',
          age: 22,
          bb: {
            name: 'Tom3',
            age: 23
          }
263
        }
264 265 266 267
      }
      const obj = Object.assign(JSON.parse<UTSJSONObject>(JSON.stringify(data2))!, JSON.parse<UTSJSONObject>(JSON.stringify(data1))!) as UTSJSONObject;
      const innerObj = obj.getJSON("aa.bb")
      expect(innerObj instanceof UTSJSONObject).toEqual(true);
268
      // #endif
269
    })
270 271
    test('stringify-with-replacer', () => {
      // #ifdef APP-ANDROID
272
      let a = JSON.stringify({ "x": 111, "y": "aaa" })
273
      expect(a).toEqual('{"x":111,"y":"aaa"}');
274 275 276 277 278
      let a1 = JSON.stringify({ "x": 111, "y": "aaa" }, function (key : any, value : any | null) : any | null {
        if (key == "x") {
          return "x"
        }
        return value
279 280
      })
      expect(a1).toEqual('{"x":"x","y":"aaa"}');
281 282 283 284 285 286
      let a2 = JSON.stringify({ "x": 111, "y": "aaa" }, function (key : any, value : any | null) : any | null {
        if (key == "x") {
          return "x"
        }
        return value
      }, 6)
287
      expect(a2.length).toEqual(36);
288 289 290 291 292 293
      let a3 = JSON.stringify({ "x": 111, "y": "aaa" }, function (key : any, value : any | null) : any | null {
        if (key == "x") {
          return "x"
        }
        return value
      }, 11)
294
      expect(a3.length).toEqual(44);
295 296 297 298 299 300 301

      let a4 = JSON.stringify({ "x": 111, "y": "aaa" }, function (key : any, value : any | null) : any | null {
        if (key == "x") {
          return "x"
        }
        return value
      }, -11)
302
      expect(a4.length).toEqual(19);
303 304

      let a5 = JSON.stringify({ "x": 111, "y": "aaa", "z": { "x": 123 } }, ["x", 'z'])
305
      expect(a5).toEqual('{"x":111,"z":{"x":123}}');
306 307

      let a6 = JSON.stringify({ "x": 111, "y": "aaa", "z": { "x": 123 } }, ["x", 'y', 'z'])
308
      expect(a6).toEqual('{"x":111,"y":"aaa","z":{"x":123}}');
309
      let a7 = JSON.stringify({ "x": 111, "y": "aaa", "z": { "x": 123 } }, ["x", 'y', 'z'], 8)
310
      expect(a7.length).toEqual(91);
311 312 313

      let a8 = JSON.stringify({ "x": 111, "y": "aaa", "z": { "x": 123 } }, ["x", 'y', 'z'], "99999")

314
      expect(a8.length).toEqual(73);
315 316
      expect(countOccurrences(a8, "99999")).toEqual(6);

317 318
      // #endif
    })
319 320 321
    
    
    
322
    test('stringify', () => {
杜庆泉's avatar
杜庆泉 已提交
323
      // #ifdef APP-ANDROID
324

杜庆泉's avatar
杜庆泉 已提交
325 326 327
      // const obj1 = { name: 'John', age: 30, address: { city: 'New York', country: 'USA' } };
      // const json1 = JSON.stringify(obj1);
      // expect(json1).toEqual('{"address":{"country":"USA","city":"New York"},"name":"John","age":30}');
328

杜庆泉's avatar
杜庆泉 已提交
329
      // #endif
330 331 332 333 334 335 336 337 338

      // #TEST JSON.stringify
      console.log(JSON.stringify({ x: 5, y: 6 }));
      // expected output: "{"x":5,"y":6}"

      console.log(JSON.stringify(new Date(2006, 0, 2, 15, 4, 5)));
      // expected output: ""2006-01-02T15:04:05.000Z""
      // #END

339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372
      const obj2 = ['apple', 'banana', 'cherry'];
      const json2 = JSON.stringify(obj2);
      expect(json2).toEqual('["apple","banana","cherry"]');

      // TODO 暂不支持多个参数
      // const obj3 = { name: 'John', age: '30' };
      // const replacer = (key : string, value : string) : string => (key === 'name' ? value.toUpperCase() : value);
      // const json3 = JSON.stringify(obj3, replacer);
      // expect(json3).toEqual('{"name":"JOHN","age":"30"}');

      // const obj4 = { name: 'John', age: 30 };
      // const json4 = JSON.stringify(obj4, null, 4);
      //             expect(json4).toEqual(`{
      //     "name": "John",
      //     "age": 30
      // }`);
      // expect(JSON.stringify({ x: 5, y: 6 })).toEqual(`{"x":5,"y":6}`);
      expect(JSON.stringify([3, 'false', false])).toEqual(`[3,"false",false]`);
      expect(JSON.stringify({})).toEqual('{}');
      expect(JSON.stringify(1002)).toEqual('1002');
      expect(JSON.stringify(1002.202)).toEqual('1002.202');
      expect(JSON.stringify(null)).toEqual('null');
      // expect(JSON.stringify(100/0.0)).toEqual('null');
      expect(JSON.stringify(true)).toEqual('true');
      expect(JSON.stringify(false)).toEqual('false');
      //console.log(JSON.stringify('foo'))
      //expect(JSON.stringify('foo')).toEqual('foo');
      expect(JSON.stringify(Math.PI)).toEqual('3.141592653589793');
      expect(JSON.stringify(Math.E)).toEqual('2.718281828459045');

      /**
       * add since 2023-09-23
       * 部分出错过的示例场景
       */
杜庆泉's avatar
杜庆泉 已提交
373
      // #ifdef APP-ANDROID
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
      const arr = [{
        "$method": "collection",
        "$param": ["type"] as Array<any>,
      }, {
        "$method": "add",
        "$param": [
          [{
            "num": 2,
            "tag": "default-tag",
          } as UTSJSONObject, {
            "num": 3,
            "tag": "default-tag",
          } as UTSJSONObject] as Array<UTSJSONObject>,
        ] as Array<any>,
      }] as Array<UTSJSONObject>
      let ret = JSON.stringify({
        $db: arr
      })
杜庆泉's avatar
杜庆泉 已提交
392
      expect(ret).toEqual('{"$db":[{"$method":"collection","$param":["type"]},{"$method":"add","$param":[[{"num":2,"tag":"default-tag"},{"num":3,"tag":"default-tag"}]]}]}')
393

杜庆泉's avatar
杜庆泉 已提交
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
      // type Msg = {
      //   id : string,
      //   method : string,
      //   params : any
      // }
      // type CallUniMethodParams = {	
      // 	method : string	
      // 	args : com.alibaba.fastjson.JSONArray
      // }
      // const msg = `{"id":"6fd6ca73-c313-48ac-ad30-87ff4eba2be8","method":"App.callUniMethod","params":{"method":"reLaunch","args":[{"url":"/pages/index/index"}]}}`
      // const jsonRet2 = JSON.parse<Msg>(msg)!

      // const paramsStr = JSON.stringify(jsonRet2.params)
      // console.log(paramsStr)
      // expect(paramsStr).toEqual('{"method":"reLaunch","args":[{"url":"/pages/index/index"}]}')
      // const params = JSON.parse<CallUniMethodParams>(paramsStr)!
      // expect(JSON.stringify(params)).toEqual('{"method":"reLaunch","args":[{"url":"/pages/index/index"}]}')
411 412 413 414 415 416 417 418 419 420 421 422 423 424


      class Stage {
        $m : string
        $p : Array<any>
        constructor() {
          this.$m = 'test'
          this.$p = ['type']
        }
      }

      const obj22 = {
        data: [new Stage()] as Array<any>
      } as UTSJSONObject
杜庆泉's avatar
杜庆泉 已提交
425
      expect(JSON.stringify(obj22)).toEqual('{"data":[{}]}')
426

杜庆泉's avatar
杜庆泉 已提交
427
      // #endif
428

429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
      type A = {
        inserted : number
      }
      const str = '{"inserted": 2}'
      const obj33 = JSON.parse<A>(str)!
      console.log('-------------------------');
      console.log(obj33.inserted);
      expectNumber(obj33.inserted).toEqualDouble(2.0)
      expect(JSON.stringify(obj33.inserted)).toEqual("2")

    })

    test('invalidField', () => {
      let str = "{\"a+b\":\"test1\",\"a-b\":2,\"class\":true}"
      let p = JSON.parseObject<PersonJSON>(str)
      expect(p?._class).toEqual(true)
      expect(p?.a_b).toEqual("test1")


      let retStr = JSON.stringify(p)
      console.log(retStr)
    })

    test('UTSJSONOject', () => {
      let t1 = "1"
      const a = {
        test() {
          t1 = "2"
          console.log("test")
        }
      };
      //console.log(a['test']);
      (a['test'] as () => void)()
      //console.log(t1);
      expect(t1).toEqual("2")
464 465 466 467
      //console.log(JSON.stringify(a));
      const map = {
        a: 1
      }.toMap()
468
      expect(map.get('a')).toEqual(1)
469

杜庆泉's avatar
杜庆泉 已提交
470 471 472
      const json = `{"result":true, "count":42}`;
      const obj = JSON.parse(json) as UTSJSONObject;
      let retStr = JSON.stringify(obj)
lizhongyi_'s avatar
lizhongyi_ 已提交
473
      // #ifdef APP-ANDROID
杜庆泉's avatar
杜庆泉 已提交
474
      expect(retStr).toEqual('{"result":true,"count":42}')
lizhongyi_'s avatar
lizhongyi_ 已提交
475
      // #endif
476 477 478 479
    })

    test('parse Map', () => {
      type A = {
480
        num : number,
481 482
      }
      const map = JSON.parse<Map<string, A>>(`{"a": {"num": 1}}`)
483
      // #ifndef APP-IOS
484
      expect(map instanceof Map).toEqual(true)
485
      // #endif
486 487 488
      expect(map?.get('a')?.num).toEqual(1)
    })

雪洛's avatar
雪洛 已提交
489
    test('parse generic type', () => {
490
      // #ifndef APP-ANDROID
雪洛's avatar
雪洛 已提交
491
      type A = {
492 493 494
        num : number,
      }
      function test<T>(json : string) : T {
雪洛's avatar
雪洛 已提交
495 496
        return JSON.parse<T>(json)!
      }
497

lizhongyi_'s avatar
lizhongyi_ 已提交
498
      // #ifndef APP-IOS
雪洛's avatar
雪洛 已提交
499 500
      const a = test<A>(`{"num": 1}`)
      expect(a.num).toEqual(1)
lizhongyi_'s avatar
lizhongyi_ 已提交
501
      // #endif
502
      // #endif
503

雪洛's avatar
雪洛 已提交
504 505
    })

506
  })
Y
yurj26 已提交
507
}