JSON.uts 14.2 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


export function testJSON() : Result {
  return describe("JSON", () => {
    test('parse', () => {
45
      // #TEST JSON.parse_tip,JSON.parse
46 47
      const json = `{"result":true, "count":42}`;
      const obj = JSON.parse(json) as UTSJSONObject;
48 49 50 51 52 53 54 55
      console.log(obj["count"]);
      // expected output: 42

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


56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
      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")

72
      // #TEST JSON.parse_1
73 74
      const json2 = '{"string":"Hello","number":42,"boolean":true,"nullValue":null,"array":[1,2,3],"object":{"nestedKey":"nestedValue"}}';
      const obj2 = JSON.parse<UTSJSONObject>(json2)!;
75
      // #END
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
      // 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', () => {
144
      // #TEST JSON.parseObject
145 146
      const json = `{"result":true, "count":42}`;
      const obj = JSON.parseObject(json);
147 148 149
      console.log(obj?.["count"])//42
      // #END

杜庆泉's avatar
杜庆泉 已提交
150 151
      expect(obj?.["count"]).toEqual(42);
      expect(obj?.["result"] as boolean).toEqual(true);
152 153

      expect(JSON.parseObject('{}')!).toEqual({});
154
      // #TEST JSON.parseObject_1
155 156 157 158 159
      const json1 = `{
			    "name": "John",
			    "id": "30"
			  }`;
      let obj2 = JSON.parseObject<UserJSON>(json1);
160 161
      console.log(obj2!.id) //30
      // #END
162 163 164 165 166 167 168 169 170 171 172 173 174 175
      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', () => {
176
      // #TEST JSON.parseArray
177 178
      const json1 = `[1,2,3]`;
      const array1 = JSON.parseArray(json1);
179 180
      console.log(array1)//[1, 2, 3]
      // #END
181 182 183 184 185 186 187
      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
杜庆泉 已提交
188
      // #ifdef APP-ANDROID
189
      // #TEST JSON.parseArray_1
190 191
      const json3 = `[{"name":"John","id":"30"},{"name":"jack","id":"21"}]`;
      const array3 = JSON.parseArray<UTSJSONObject>(json3);
192 193
      console.log((array3![0])["name"])//"John"
      // #END
杜庆泉's avatar
杜庆泉 已提交
194 195
      expect((array3![0])["name"]).toEqual("John");
      // #endif
196
    })
197

198 199
    test('merge-test-1', () => {
      // #ifdef APP-ANDROID
200 201 202 203 204 205 206 207 208 209 210 211 212
      const data1 = {
        name: 'Tom1',
        age: 21
      };

      const data2 = {
        aa: {
          name: 'Tom2',
          age: 22,
          bb: {
            name: 'Tom3',
            age: 23
          }
213
        }
214 215 216 217
      }
      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);
218
      // #endif
219
    })
220 221
    test('stringify-with-replacer', () => {
      // #ifdef APP-ANDROID
222
      let a = JSON.stringify({ "x": 111, "y": "aaa" })
223
      expect(a).toEqual('{"x":111,"y":"aaa"}');
224 225 226 227 228
      let a1 = JSON.stringify({ "x": 111, "y": "aaa" }, function (key : any, value : any | null) : any | null {
        if (key == "x") {
          return "x"
        }
        return value
229 230
      })
      expect(a1).toEqual('{"x":"x","y":"aaa"}');
231 232 233 234 235 236
      let a2 = JSON.stringify({ "x": 111, "y": "aaa" }, function (key : any, value : any | null) : any | null {
        if (key == "x") {
          return "x"
        }
        return value
      }, 6)
237
      expect(a2.length).toEqual(36);
238 239 240 241 242 243
      let a3 = JSON.stringify({ "x": 111, "y": "aaa" }, function (key : any, value : any | null) : any | null {
        if (key == "x") {
          return "x"
        }
        return value
      }, 11)
244
      expect(a3.length).toEqual(44);
245 246 247 248 249 250 251

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

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

      let a6 = JSON.stringify({ "x": 111, "y": "aaa", "z": { "x": 123 } }, ["x", 'y', 'z'])
258
      expect(a6).toEqual('{"x":111,"y":"aaa","z":{"x":123}}');
259
      let a7 = JSON.stringify({ "x": 111, "y": "aaa", "z": { "x": 123 } }, ["x", 'y', 'z'], 8)
260
      expect(a7.length).toEqual(91);
261 262 263

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

264
      expect(a8.length).toEqual(73);
265 266 267
      expect(countOccurrences(a8, "99999")).toEqual(6);


268 269
      // #endif
    })
270
    test('stringify', () => {
杜庆泉's avatar
杜庆泉 已提交
271
      // #ifdef APP-ANDROID
272

杜庆泉's avatar
杜庆泉 已提交
273 274 275
      // 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}');
276

杜庆泉's avatar
杜庆泉 已提交
277
      // #endif
278 279 280 281 282 283 284 285 286 287 288 289

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

      console.log(JSON.stringify([3, 'false', boolean]));
      // expected output: "[3,"false",false]"

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

290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323
      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
杜庆泉 已提交
324
      // #ifdef APP-ANDROID
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342
      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
杜庆泉 已提交
343
      expect(ret).toEqual('{"$db":[{"$method":"collection","$param":["type"]},{"$method":"add","$param":[[{"num":2,"tag":"default-tag"},{"num":3,"tag":"default-tag"}]]}]}')
344

杜庆泉's avatar
杜庆泉 已提交
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
      // 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"}]}')
362 363 364 365 366 367 368 369 370 371 372 373 374 375


      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
杜庆泉 已提交
376
      expect(JSON.stringify(obj22)).toEqual('{"data":[{}]}')
377

杜庆泉's avatar
杜庆泉 已提交
378
      // #endif
379

380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
      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")
415 416 417 418
      //console.log(JSON.stringify(a));
      const map = {
        a: 1
      }.toMap()
419
      expect(map.get('a')).toEqual(1)
420

杜庆泉's avatar
杜庆泉 已提交
421 422 423
      const json = `{"result":true, "count":42}`;
      const obj = JSON.parse(json) as UTSJSONObject;
      let retStr = JSON.stringify(obj)
lizhongyi_'s avatar
lizhongyi_ 已提交
424
      // #ifdef APP-ANDROID
杜庆泉's avatar
杜庆泉 已提交
425
      expect(retStr).toEqual('{"result":true,"count":42}')
lizhongyi_'s avatar
lizhongyi_ 已提交
426
      // #endif
427 428 429 430
    })

    test('parse Map', () => {
      type A = {
431
        num : number,
432 433
      }
      const map = JSON.parse<Map<string, A>>(`{"a": {"num": 1}}`)
434
      // #ifndef APP-IOS
435
      expect(map instanceof Map).toEqual(true)
436
      // #endif
437 438 439
      expect(map?.get('a')?.num).toEqual(1)
    })

雪洛's avatar
雪洛 已提交
440
    test('parse generic type', () => {
441
      // #ifndef APP-ANDROID
雪洛's avatar
雪洛 已提交
442
      type A = {
443 444 445
        num : number,
      }
      function test<T>(json : string) : T {
雪洛's avatar
雪洛 已提交
446 447
        return JSON.parse<T>(json)!
      }
448

lizhongyi_'s avatar
lizhongyi_ 已提交
449
      // #ifndef APP-IOS
雪洛's avatar
雪洛 已提交
450 451
      const a = test<A>(`{"num": 1}`)
      expect(a.num).toEqual(1)
lizhongyi_'s avatar
lizhongyi_ 已提交
452
      // #endif
453
      // #endif
454

雪洛's avatar
雪洛 已提交
455 456
    })

457
  })
Y
yurj26 已提交
458
}