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; } function countOccurrences(str:string, substr:string):number { let count = 0 let position = 0 while (true) { position = str.indexOf(substr, position) if (position == -1) break count++ position += substr.length } return count; } export function testJSON() : Result { return describe("JSON", () => { test('parse', () => { const json = `{"result":true, "count":42}`; const obj = JSON.parse(json) as UTSJSONObject; 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") const json2 = '{"string":"Hello","number":42,"boolean":true,"nullValue":null,"array":[1,2,3],"object":{"nestedKey":"nestedValue"}}'; const obj2 = JSON.parse(json2)!; // 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(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', () => { const json = `{"result":true, "count":42}`; const obj = JSON.parseObject(json); expect(obj?.["count"]).toEqual(42); expect(obj?.["result"] as boolean).toEqual(true); expect(JSON.parseObject('{}')!).toEqual({}); const json1 = `{ "name": "John", "id": "30" }`; let obj2 = JSON.parseObject(json1); expect(obj2!.id).toEqual("30"); const json2 = `{ "id": "30" }`; let obj3 = JSON.parseObject(json2); expect(obj3!.id).toEqual("30"); const json3 = `{ "name": "John" }`; let obj4 = JSON.parseObject(json3); expect(obj4).toEqual(null); }) test('parseArray', () => { const json1 = `[1,2,3]`; const array1 = JSON.parseArray(json1); expect(array1).toEqual([1, 2, 3]); const json2 = `[1,"hello world",3]`; const array2 = JSON.parseArray(json2); expect(array2).toEqual([1, "hello world", 3]); // #ifdef APP-ANDROID const json3 = `[{"name":"John","id":"30"},{"name":"jack","id":"21"}]`; const array3 = JSON.parseArray(json3); expect((array3![0])["name"]).toEqual("John"); // #endif }) test('merge-test-1', () => { // #ifdef APP-ANDROID const data1 = { name: 'Tom1', age: 21 }; const data2 = { aa: { name: 'Tom2', age: 22, bb: { name: 'Tom3', age: 23 } } } const obj = Object.assign(JSON.parse(JSON.stringify(data2))!, JSON.parse(JSON.stringify(data1))!) as UTSJSONObject; const innerObj = obj.getJSON("aa.bb") expect(innerObj instanceof UTSJSONObject).toEqual(true); // #endif }) test('stringify-with-replacer', () => { // #ifdef APP-ANDROID let a = JSON.stringify({"x":111,"y":"aaa"}) expect(a).toEqual('{"x":111,"y":"aaa"}'); let a1 = JSON.stringify({"x":111,"y":"aaa"},function(key:any,value:any|null):any|null{ if(key == "x"){ return "x" } return value }) expect(a1).toEqual('{"x":"x","y":"aaa"}'); let a2 = JSON.stringify({"x":111,"y":"aaa"},function(key:any,value:any|null):any|null{ if(key == "x"){ return "x" } return value },6) expect(a2.length).toEqual(36); let a3 = JSON.stringify({"x":111,"y":"aaa"},function(key:any,value:any|null):any|null{ if(key == "x"){ return "x" } return value },11) expect(a3.length).toEqual(44); let a4 = JSON.stringify({"x":111,"y":"aaa"},function(key:any,value:any|null):any|null{ if(key == "x"){ return "x" } return value },-11) expect(a4.length).toEqual(19); let a5 = JSON.stringify({"x":111,"y":"aaa","z":{"x":123}},["x",'z']) expect(a5).toEqual('{"x":111,"z":{"x":123}}'); let a6 = JSON.stringify({"x":111,"y":"aaa","z":{"x":123}},["x",'y','z']) expect(a6).toEqual('{"x":111,"y":"aaa","z":{"x":123}}'); let a7 = JSON.stringify({"x":111,"y":"aaa","z":{"x":123}},["x",'y','z'],8) expect(a7.length).toEqual(91); let a8 = JSON.stringify({"x":111,"y":"aaa","z":{"x":123}},["x",'y','z'],"99999") expect(a8.length).toEqual(73); expect(countOccurrences(a8,"99999")).toEqual(6); // #endif }) test('stringify', () => { // #ifdef APP-ANDROID // 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}'); // #endif 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 * 部分出错过的示例场景 */ // #ifdef APP-ANDROID const arr = [{ "$method": "collection", "$param": ["type"] as Array, }, { "$method": "add", "$param": [ [{ "num": 2, "tag": "default-tag", } as UTSJSONObject, { "num": 3, "tag": "default-tag", } as UTSJSONObject] as Array, ] as Array, }] as Array let ret = JSON.stringify({ $db: arr }) expect(ret).toEqual('{"$db":[{"$method":"collection","$param":["type"]},{"$method":"add","$param":[[{"num":2,"tag":"default-tag"},{"num":3,"tag":"default-tag"}]]}]}') // 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)! // const paramsStr = JSON.stringify(jsonRet2.params) // console.log(paramsStr) // expect(paramsStr).toEqual('{"method":"reLaunch","args":[{"url":"/pages/index/index"}]}') // const params = JSON.parse(paramsStr)! // expect(JSON.stringify(params)).toEqual('{"method":"reLaunch","args":[{"url":"/pages/index/index"}]}') class Stage { $m : string $p : Array constructor() { this.$m = 'test' this.$p = ['type'] } } const obj22 = { data: [new Stage()] as Array } as UTSJSONObject expect(JSON.stringify(obj22)).toEqual('{"data":[{}]}') // #endif type A = { inserted : number } const str = '{"inserted": 2}' const obj33 = JSON.parse(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(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") //console.log(JSON.stringify(a)); const map = { a: 1 }.toMap() expect(map.get('a')).toEqual(1) const json = `{"result":true, "count":42}`; const obj = JSON.parse(json) as UTSJSONObject; let retStr = JSON.stringify(obj) // #ifdef APP-ANDROID expect(retStr).toEqual('{"result":true,"count":42}') // #endif }) test('parse Map', () => { type A = { num: number, } const map = JSON.parse>(`{"a": {"num": 1}}`) // #ifndef APP-IOS expect(map instanceof Map).toEqual(true) // #endif expect(map?.get('a')?.num).toEqual(1) }) test('parse generic type', () => { type A = { num: number, } function test(json: string): T { return JSON.parse(json)! } const a = test(`{"num": 1}`) expect(a.num).toEqual(1) }) }) }