提交 531659aa 编写于 作者: dcloud_wdl's avatar dcloud_wdl

merge origin/alpha

## 1.1.6
* update 4.15.2024050802
## 1.0.16
* update 4.21.2024061818-alpha
## 1.1.5
* update 4.14.2024043008
## 1.0.15
* update 4.19.2024060704-alpha
## 1.0.14
* update 4.18.2024060311-alpha
## 1.0.13
* update 4.17.2024051110-alpha
## 1.0.12
* update 4.16.2024051009-alpha
## 1.0.11
* update 4.14.2024042905-alpha
......
......@@ -39,7 +39,7 @@ function parseDescribes() {
};
module.exports = {
testTimeout: 10000,
testTimeout: 20000,
reporters: [
'default'
],
......
{
"id": "hello-uts",
"name": "hello-uts",
"displayName": "hello-uts",
"version": "1.1.6",
"id": "hello-uts-alpha",
"name": "hello-uts-alpha",
"displayName": "hello-uts-alpha",
"version": "1.0.16",
"description": "UTS插件示例项目",
"repository": "https://gitcode.net/dcloud/hello-uts",
"keywords": [
......
......@@ -156,7 +156,10 @@
"enablePullDownRefresh": false
}
},
}
// #endif
// #ifdef APP-Android
,
{
"path": "pages/SyntaxCase/utsAndroid",
"style": {
......@@ -164,14 +167,16 @@
"enablePullDownRefresh": false
}
},
}
// #endif
// #ifdef APP-iOS
,
{
"path": "pages/SyntaxCase/utsiOS",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}
// #endif
......
<template>
<!-- #ifdef APP-ANDROID -->
<!-- #ifdef APP -->
<scroll-view style="flex: 1">
<!-- #endif -->
<view>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-hello-text"> 逐一点击执行,观察测试反馈 </view>
......@@ -18,6 +16,7 @@
<button @click="dispatchAsyncClick">任务分发测试</button>
<button @click="pathTestClick">路径转换测试</button>
<button @click="privacyStateClick">隐私协议状态测试</button>
<button @click="privacyStateCallBackClick">隐私协议回调测试</button>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-hello-text">
1. 当前页面已通过initAppLifecycle函数注册了生命周期监听。
......@@ -42,229 +41,346 @@
</view>
<button @tap="getDeviceInfoClick">获取设备基础信息</button>
<button @tap="getFileProviderUriClick">使用外部应用访问私有文件</button>
<button @tap="activityCallback">注册activity 回调方法</button>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-hello-text">
点击注册activity 回调方法后,可以手动切换其他APP再返回,可在控制台和界面观察事件日志
</view>
</view>
<view class="uni-padding-wrap uni-common-mt">
<view class="text-box" scroll-y="true">
<text>{{ cbText }}</text>
</view>
</view>
<button @tap="unRegActivityCallback">取消注册activity 回调方法</button>
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
<!-- #endif -->
</template>
<script>
<!-- #ifdef APP-ANDROID -->
import {
getAppContextTest,
getUniActivityTest,
getJavaClassTest,
getAppTempPathTest,
typeofClickTest,
gotoSystemPermissionActivityTest,
arrayPermissionFlowTest,
singlePermissionFlowTest,
dispatchAsyncTest,
convert2AbsFullPathTest,
unRegLifecycle,
initAppLifecycle,
gotoCameraTake,
getDeviceInfoTest,
privacyStateTest,
} from '@/uni_modules/uts-platform-api'
import File from 'java.io.File';
import Intent from 'android.content.Intent';
import {
getAppContextTest,
getUniActivityTest,
getJavaClassTest,
getAppTempPathTest,
typeofClickTest,
gotoSystemPermissionActivityTest,
arrayPermissionFlowTest,
singlePermissionFlowTest,
dispatchAsyncTest,
convert2AbsFullPathTest,
unRegLifecycle,
initAppLifecycle,
gotoCameraTake,
getDeviceInfoTest,
privacyStateTest
} from '@/uni_modules/uts-platform-api'
// #ifdef APP-ANDROID
import {
UTSAcvitiyLifeCycleCallback,
UTSAcvitiyKeyEventCallback,
UTSActivityWindowCallback,
UTSActivityCallback,
UTSActivityComponentCallback,
onCallbackChange
} from '@/uni_modules/uts-syntaxcase'
// #endif
/**
* 测试在页面生命周期之外,使用api
*/
export default {
data() {
return {
text: '',
selectImage: '',
}
},
onLoad: function () {
let that = this
initAppLifecycle(function (eventLog) {
// 展示捕捉到的声明周期日志
let nextLine = that.text + eventLog
that.text = nextLine
let nextLineFlag = that.text + '\n'
that.text = nextLineFlag
})
},
methods: {
privacyStateClick() {
privacyStateTest(function (ret, desc) {
if (ret) {
uni.showToast({
title: '测试通过',
})
} else {
uni.showToast({
icon: 'none',
title: '失败:' + desc,
})
}
})
},
getDeviceInfoClick() {
this.text = getDeviceInfoTest()
},
testGoOtherActivity() {
var that = this
let ret = gotoCameraTake(function (file) {
// 展示捕捉到的声明周期日志
console.log(file)
that.selectImage = 'file://' + file
})
if (!ret) {
uni.showToast({
icon: 'none',
title: '测试失败',
})
}
},
testUnRegLifecycle() {
// 取消注册生命周期
unRegLifecycle()
},
getJavaClassClick() {
if (getJavaClassTest()) {
uni.showToast({
title: '测试通过'
})
} else {
uni.showToast({
icon: 'error',
title: '测试失败'
})
}
},
getAppContextClick() {
if (getAppContextTest()) {
uni.showToast({
title: '测试通过',
})
} else {
uni.showToast({
icon: 'error',
title: '测试失败',
})
}
},
import File from 'java.io.File';
import Intent from 'android.content.Intent';
getUniActivityClick() {
if (getUniActivityTest()) {
uni.showToast({
title: '测试通过',
})
} else {
uni.showToast({
icon: 'error',
title: '测试失败',
})
/**
* 测试在页面生命周期之外,使用api
*/
export default {
data() {
return {
text: '',
cbText: '',
selectImage: '',
callback: [] as Any[]
}
},
pathTestClick() {
if (convert2AbsFullPathTest()) {
uni.showToast({
title: '测试通过',
})
} else {
uni.showToast({
icon: 'error',
title: '测试失败',
})
}
unmounted() {
// #ifdef APP-ANDROID
this.unRegActivityCallback()
// #endif
},
getFileProviderUriClick() {
let file = new File(UTSAndroid.getResourcePath("static/logo.png"))
const uri = UTSAndroid.getFileProviderUri(file)
console.log("uri",uri.toString())
const intent = new Intent(Intent.ACTION_VIEW, uri)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 添加权限标志
const context = UTSAndroid.getUniActivity()!;
context.startActivity(intent);
onLoad: function () {
let that = this
initAppLifecycle(function (eventLog) {
// 展示捕捉到的声明周期日志
let nextLine = that.text + eventLog
that.text = nextLine
let nextLineFlag = that.text + '\n'
that.text = nextLineFlag
})
},
getAppTempPathClick() {
if (getAppTempPathTest()) {
uni.showToast({
title: '测试通过',
methods: {
privacyStateClick() {
privacyStateTest(function (ret, desc) {
if (ret) {
uni.showToast({
title: '测试通过',
})
} else {
uni.showToast({
icon: 'none',
title: '失败:' + desc,
})
}
})
} else {
uni.showToast({
icon: 'error',
title: '测试失败',
},
privacyStateCallBackClick() {
let isAgree : boolean = true
const cb = (ret : PrivacyOption) => {
console.log('privacyStateCallBackTest->' + ret.isAgree)
if (ret.isAgree == isAgree) {
uni.showToast({
title: '测试通过'
})
} else {
uni.showToast({
icon: 'none',
title: '失败'
})
}
}
// 先重置用户同意状态
UTSAndroid.onPrivacyAgreeChange(cb)
UTSAndroid.setPrivacyAgree(isAgree)
UTSAndroid.offPrivacyAgreeChange(cb)
setTimeout(function () {
console.log('privacyStateCallBackTest->false')
UTSAndroid.setPrivacyAgree(false)
}, 5000);
},
getDeviceInfoClick() {
this.text = getDeviceInfoTest()
},
testGoOtherActivity() {
var that = this
let ret = gotoCameraTake(function (file) {
// 展示捕捉到的声明周期日志
console.log(file)
that.selectImage = 'file://' + file
})
}
},
dispatchAsyncClick() {
dispatchAsyncTest(function (ret, desc) {
if (ret) {
if (!ret) {
uni.showToast({
icon: 'none',
title: '测试失败',
})
}
},
testUnRegLifecycle() {
// 取消注册生命周期
unRegLifecycle()
},
getJavaClassClick() {
if (getJavaClassTest()) {
uni.showToast({
title: '测试通过'
})
} else {
uni.showToast({
icon: 'error',
title: '测试失败'
})
}
},
getAppContextClick() {
if (getAppContextTest()) {
uni.showToast({
title: '测试通过',
})
} else {
uni.showToast({
icon: 'none',
title: '失败:' + desc,
icon: 'error',
title: '测试失败',
})
}
})
},
typeofClick() {
if (typeofClickTest()) {
uni.showToast({
title: '测试通过',
})
} else {
uni.showToast({
icon: 'error',
title: '测试失败',
})
}
},
},
gotoSystemPermissionActivityClick() {
gotoSystemPermissionActivityTest()
},
arrayPermissionFlowClick() {
arrayPermissionFlowTest(function (ret, desc) {
if (ret) {
getUniActivityClick() {
if (getUniActivityTest()) {
uni.showToast({
icon: 'none',
title: '测试通过',
})
} else {
uni.showToast({
icon: 'none',
title: '失败:' + desc,
icon: 'error',
title: '测试失败',
})
}
})
},
singlePermissionFlowClick() {
singlePermissionFlowTest(function (ret, desc) {
if (ret) {
},
pathTestClick() {
if (convert2AbsFullPathTest()) {
uni.showToast({
icon: 'none',
title: '测试通过',
})
} else {
uni.showToast({
icon: 'none',
title: '失败:' + desc,
icon: 'error',
title: '测试失败',
})
}
})
},
getFileProviderUriClick() {
let file = new File(UTSAndroid.getResourcePath("static/logo.png"))
const uri = UTSAndroid.getFileProviderUri(file)
console.log("uri", uri.toString())
const intent = new Intent(Intent.ACTION_VIEW, uri)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 添加权限标志
const context = UTSAndroid.getUniActivity()!;
context.startActivity(intent);
},
getAppTempPathClick() {
if (getAppTempPathTest()) {
uni.showToast({
title: '测试通过',
})
} else {
uni.showToast({
icon: 'error',
title: '测试失败',
})
}
},
dispatchAsyncClick() {
dispatchAsyncTest(function (ret, desc) {
if (ret) {
uni.showToast({
title: '测试通过',
})
} else {
uni.showToast({
icon: 'none',
title: '失败:' + desc,
})
}
})
},
typeofClick() {
if (typeofClickTest()) {
uni.showToast({
title: '测试通过',
})
} else {
uni.showToast({
icon: 'error',
title: '测试失败',
})
}
},
gotoSystemPermissionActivityClick() {
gotoSystemPermissionActivityTest()
},
arrayPermissionFlowClick() {
arrayPermissionFlowTest(function (ret, desc) {
if (ret) {
uni.showToast({
icon: 'none',
title: '测试通过',
})
} else {
uni.showToast({
icon: 'none',
title: '失败:' + desc,
})
}
})
},
singlePermissionFlowClick() {
singlePermissionFlowTest(function (ret, desc) {
if (ret) {
uni.showToast({
icon: 'none',
title: '测试通过',
})
} else {
uni.showToast({
icon: 'none',
title: '失败:' + desc,
})
}
})
},
// #ifdef APP-ANDROID
// #ifdef UNI-APP-X
activityCallback() {
var that = this
onCallbackChange(function (eventLog : string) {
// 展示捕捉到的声明周期日志
let nextLine = that.cbText + eventLog
that.cbText = nextLine
let nextLineFlag = that.cbText + '\n'
that.cbText = nextLineFlag
})
let index = getCurrentPages().length - 1
let page = getCurrentPages()[index]
console.log('page route=' + page.route)
this.callback.push(new UTSAcvitiyLifeCycleCallback())
this.callback.push(new UTSActivityWindowCallback())
this.callback.push(new UTSAcvitiyKeyEventCallback())
this.callback.push(new UTSActivityCallback(), page.route)
this.callback.push(new UTSActivityComponentCallback())
this.callback.forEach((value) => {
if (value instanceof UTSAcvitiyLifeCycleCallback) {
UTSAndroid.onActivityCallback(value,page.route)
}
if (value instanceof UTSActivityWindowCallback) {
UTSAndroid.onActivityCallback(value)
}
if (value instanceof UTSAcvitiyKeyEventCallback) {
UTSAndroid.onActivityCallback(value)
}
if (value instanceof UTSActivityCallback) {
UTSAndroid.onActivityCallback(value)
}
if (value instanceof UTSActivityComponentCallback) {
UTSAndroid.onActivityCallback(value)
}
})
},
unRegActivityCallback() {
this.callback.forEach((value) => {
if (value instanceof UTSAcvitiyLifeCycleCallback) {
UTSAndroid.offActivityCallback(value)
}
if (value instanceof UTSActivityWindowCallback) {
UTSAndroid.offActivityCallback(value)
}
if (value instanceof UTSAcvitiyKeyEventCallback) {
UTSAndroid.offActivityCallback(value)
}
if (value instanceof UTSActivityCallback) {
UTSAndroid.offActivityCallback(value)
}
if (value instanceof UTSActivityComponentCallback) {
UTSAndroid.offActivityCallback(value)
}
})
}
// #endif
// #endif
},
},
}
<!-- #endif -->
}
</script>
<style>
.testButton {
width: 100%;
}
</style>
.testButton {
width: 100%;
}
</style>
\ No newline at end of file
......@@ -17,6 +17,7 @@
<button @click="dispatchAsyncClick">任务分发测试</button>
<button @click="pathTestClick">路径转换测试</button>
<button @click="privacyStateClick">隐私协议状态测试</button>
<button @click="privacyStateCallBackClick">隐私协议回调测试</button>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-hello-text">
1. 当前页面已通过initAppLifecycle函数注册了生命周期监听。
......@@ -60,7 +61,8 @@
initAppLifecycle,
gotoCameraTake,
getDeviceInfoTest,
privacyStateTest
privacyStateTest,
privacyStateCallBackTest
} from '@/uni_modules/uts-platform-api'
/**
* 测试在页面生命周期之外,使用api
......@@ -95,6 +97,20 @@
}
})
},
privacyStateCallBackClick() {
privacyStateCallBackTest(function(ret, desc) {
if (ret) {
uni.showToast({
title: '测试通过'
})
} else {
uni.showToast({
icon: 'none',
title: '失败:' + desc
})
}
})
},
getDeviceInfoClick(){
this.text = getDeviceInfoTest()
},
......
......@@ -18,7 +18,7 @@
</view>
</template>
<script lang="ts">
import { gotoDemoActivity } from "@/uni_modules/uts-nativepage";
import { gotoDemoActivity,sayHelloFromJar } from "@/uni_modules/uts-nativepage";
import { getBatteryInfo, GetBatteryInfoOptions } from "@/uni_modules/uts-getbatteryinfo";
type Page = {
......@@ -66,6 +66,9 @@
pages: [{
name: "自定义activity(需自定义基座)",
function: "testGotoDemoActivity"
},{
name: "调用jar中的方法",
function: "testNativeJar"
}] as Page[]
}
] as ListItem[],
......@@ -93,6 +96,8 @@
break
case 'testGotoDemoActivity':
this.testGotoDemoActivity()
case 'testNativeJar':
this.testNativeJar()
break
}
return
......@@ -111,6 +116,13 @@
});
}
} as GetBatteryInfoOptions)
},
testNativeJar() {
let ret = sayHelloFromJar();
uni.showToast({
icon: 'none',
title: '来自jar中的返回值:' + ret
})
},
testGotoDemoActivity() {
let ret = gotoDemoActivity();
......
......@@ -18,8 +18,13 @@
android:resource="@xml/custom_accessibility_service_config" />
</service>
<service android:name="uts.sdk.modules.utsNativepage.ForeService" />
<activity android:name="uts.sdk.modules.utsNativepage.DemoActivity"></activity>
<service android:name="uts.sdk.modules.utsNativepage.ForeService" android:exported="true"/>
<activity android:name="uts.sdk.modules.utsNativepage.DemoActivity" android:exported="true">
<intent-filter>
<action android:name="uts.sdk.modules.demo" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<!--桌面widget组件注册-->
<receiver
android:name="uts.sdk.modules.utsNativepage.DoAppWidget"
......
{
"dependencies": [
"androidx.recyclerview:recyclerview:1.0.0"
"androidx.recyclerview:recyclerview:1.0.0",
"androidx.core:core:1.10.1"
]
}
......@@ -16,6 +16,10 @@ import Build from 'android.os.Build';
import IBinder from 'android.os.IBinder';
import Toast from 'android.widget.Toast';
import ShortcutInfoCompat from 'androidx.core.content.pm.ShortcutInfoCompat'
import ShortcutManagerCompat from 'androidx.core.content.pm.ShortcutManagerCompat'
import IconCompat from 'androidx.core.graphics.drawable.IconCompat'
import Service from 'android.app.Service';
import System from 'java.lang.System';
......@@ -27,18 +31,46 @@ import LayoutInflater from 'android.view.LayoutInflater';
import LinearLayoutManager from 'androidx.recyclerview.widget.LinearLayoutManager';
export {DoAppWidget} from "./DoAppWidget.uts"
import Application from 'android.app.Application';
import Log from 'android.util.Log';
import File from 'java.io.File';
import Uri from 'android.net.Uri';
export * from './CustomAccessibilityService.uts'
import SayHelloTest from 'com.test.sayhello.SayHelloTest'
export function sayHelloFromJar(): string {
// 这里的逻辑是为了判断 当前的自定义activity 是否注册了,并以此为条件判断是否是自定义基座
let hasXActivityIntegration = true
try{
let packageManager = UTSAndroid.getUniActivity()!.getPackageManager();
let intent = new Intent(UTSAndroid.getUniActivity(),DemoActivity().javaClass);
let resolveInfo = packageManager.queryIntentActivities(intent,0);
console.log(resolveInfo.size)
if(resolveInfo.size == 0){
hasXActivityIntegration = false;
}
}catch(e:Exception){
console.log(e);
hasXActivityIntegration = false;
}
if(!hasXActivityIntegration){
return "需要在自定义基座运行";
}
return SayHelloTest().say()
}
export class AppHookProxy implements UTSAndroidHookProxy {
override onCreate(application: Application) {
//当前应用是否 取得用户同意隐私协议
android.util.Log.d("AppHookProxy", "AppHookProxy--onCreate---")
if(UTSAndroid.isPrivacyAgree()) {
//onCreate 初始化三方SDK
android.util.Log.d("AppHookProxy", "AppHookProxy--onCreate---isPrivacyAgree")
}
//当前应用是否 取得用户同意隐私协议
Log.d("AppHookProxy", "AppHookProxy--onCreate---")
// 初始化快捷方式
initShortCut()
if(UTSAndroid.isPrivacyAgree()) {
//onCreate 初始化三方SDK
Log.d("AppHookProxy", "AppHookProxy--onCreate---isPrivacyAgree")
}
}
}
......@@ -50,19 +82,19 @@ class ForeService extends Service {
super();
}
override onCreate():void {
super.onCreate();
override onCreate():void {
super.onCreate();
console.log("onCreate");
}
}
override onBind(_intent?: Intent): IBinder|null{
return null;
}
}
override onStartCommand(intent:Intent ,flags:Int ,startId:Int ):Int {
override onStartCommand(intent:Intent ,flags:Int ,startId:Int ):Int {
let mBuilder = new NotificationCompat.Builder(this,"uts-test");
let mBuilder = new NotificationCompat.Builder(this,"uts-test");
// 点击后让通知将消失
mBuilder.setAutoCancel(true)
......@@ -321,6 +353,48 @@ class IntentRunable extends Runnable{
UTSAndroid.getUniActivity()!.startActivity(intent);
}
}
/**
* 给当前应用设置快捷方式
* 仅支持 android 7.1 以上版本,自定义基座查看
*/
function initShortCut() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
console.log("桌面快捷方式 仅支持android 7.1 以上版本")
return;
}
// 注意 id 不能重复
let shortcutBuilder = ShortcutInfoCompat.Builder(UTSAndroid.getAppContext()!, "id1");
shortcutBuilder.setShortLabel("官网")
shortcutBuilder.setLongLabel("访问官网")
shortcutBuilder.setIcon(IconCompat.createWithResource(UTSAndroid.getAppContext()!, R.drawable.icon_short))
shortcutBuilder.setIntent(
new Intent(
Intent.ACTION_VIEW,
Uri.parse("https://dcloud.io/")
)
)
let shortcut = shortcutBuilder.build()
// 注意 id 不能重复
let shortcutBuilder2 = ShortcutInfoCompat.Builder(UTSAndroid.getAppContext()!, "id2");
shortcutBuilder2.setShortLabel("示例界面")
shortcutBuilder2.setLongLabel("打开示例界面,最多可以写25个字")
shortcutBuilder2.setIcon(IconCompat.createWithResource(UTSAndroid.getAppContext()!, R.drawable.icon_short))
shortcutBuilder2.setIntent(
new Intent(
"uts.sdk.modules.demo"
)
)
let shortcut2 = shortcutBuilder2.build()
// #ifdef UNI-APP-X
ShortcutManagerCompat.setDynamicShortcuts(UTSAndroid.getAppContext()!, [shortcut,shortcut2].toKotlinList())
// #endif
// #ifndef UNI-APP-X
console.log("当前示例仅支持uni-app x环境")
// #endif
}
@Suppress("DEPRECATION")
export function gotoDemoActivity():boolean {
......
......@@ -81,6 +81,27 @@ export function privacyStateTest(callback : (ret : boolean, desc : string) => vo
}
export function privacyStateCallBackTest(callback : (ret : boolean, desc : string) => void) {
let isAgree : boolean = true
const cb = (ret : PrivacyOption) => {
console.log('privacyStateCallBackTest->' + ret.isAgree)
if (ret.isAgree == isAgree) {
callback(true, "pass")
} else {
callback(false, "callback error")
}
}
// 先重置用户同意状态
UTSAndroid.onPrivacyAgreeChange(cb)
UTSAndroid.setPrivacyAgree(isAgree)
UTSAndroid.offPrivacyAgreeChange(cb)
setTimeout(function () {
console.log('privacyStateCallBackTest->false')
UTSAndroid.setPrivacyAgree(false)
}, 5000);
}
/**
* UTSAndroid.getAppTempPath 测试示例
*/
......
......@@ -397,10 +397,10 @@ function convertBoolTest(): UTSiOSTestResult {
/* 将数据转换为 NSNumber */
function convertNumberTest(): UTSiOSTestResult {
let ret: NSNumber = UTSiOS.convertNumber(1000)
let res: UTSiOSTestResult = {
let ret: NSNumber | null = UTSiOS.convertNumber(1000)
let res: UTSiOSTestResult = {
key: "1000 转成number",
value: `${ret.intValue}`,
value: `${ret?.intValue}`,
passed: true
}
return res;
......
import { RequestTask, SyncOptions } from "./interface.uts";
import { log } from "./utils.uts";
export type AsyncOptions = {
type : string;
success : (res : string) => void;
fail : (res : string) => void;
complete : (res : string) => void;
type : string;
success : (res : string) => void;
fail : (res : string) => void;
complete : (res : string) => void;
};
export type {
SyncOptions
SyncOptions
} from "./interface.uts";
type SyntaxResult = {
name : string
name : string
};
type SyncResult = {
msg : string
msg : string
}
/**
......@@ -29,140 +29,285 @@ export const MAX = 100;
* @returns
*/
export function testSync(msg : string) : SyncResult {
console.log("log test");
log("log test1");
console.log("log test");
log("log test1");
const res : SyncResult = {
msg: `hello ${msg}`
}
return res
// return {
// msg: `hello ${msg}`,
// };
const res : SyncResult = {
msg: `hello ${msg}`
}
return res
// return {
// msg: `hello ${msg}`,
// };
}
/**
* 导出一个同步方法(触发了数组越界异常)
*/
export function testSyncError() {
const arr : string[] = [];
console.log(arr[1]);
const arr : string[] = [];
console.log(arr[1]);
}
/**
* 导出一个带callback的同步方法
* @param opts
*/
export function testSyncWithCallback(opts : AsyncOptions) : SyntaxResult {
if (opts.type == "success") {
opts.success("success");
} else {
opts.fail("fail");
}
opts.complete("complete");
const res : SyntaxResult = {
name: "testSyncWithCallback"
}
return res;
// return { name: "testSyncWithCallback" };
if (opts.type == "success") {
opts.success("success");
} else {
opts.fail("fail");
}
opts.complete("complete");
const res : SyntaxResult = {
name: "testSyncWithCallback"
}
return res;
// return { name: "testSyncWithCallback" };
}
async function testAwaitPromise(res : SyntaxResult) : Promise<SyntaxResult> {
// #ifdef APP-ANDROID
return await new Promise(function (resolve : (res : SyntaxResult) => void) {
resolve(res)
})
// #endif
// #ifndef APP-ANDROID
return res
// #endif
// #ifdef APP-ANDROID
return await new Promise(function (resolve : (res : SyntaxResult) => void) {
resolve(res)
})
// #endif
// #ifndef APP-ANDROID
return res
// #endif
}
/**
* 导出一个异步方法
* @returns
*/
export async function testAsync(opts : AsyncOptions) : Promise<SyntaxResult> {
if (opts.type == "success") {
opts.success("success");
} else {
opts.fail("fail");
}
opts.complete("complete");
const res : SyntaxResult = {
name: "testAsync"
}
return await testAwaitPromise(res);
// return { name: "testAsync" };
}
export async function testAsyncParam3(id:number,name:string,opts : AsyncOptions) : Promise<SyntaxResult> {
console.log("id",id,"name",name)
if (opts.type == "success") {
opts.success("success");
} else {
opts.fail("fail");
}
opts.complete("complete");
const res : SyntaxResult = {
name: "testUtsAsyncMulitParam"
}
return await testAwaitPromise(res);
// return { name: "testAsync" };
}
if (opts.type == "success") {
opts.success("success");
} else {
opts.fail("fail");
}
opts.complete("complete");
const res : SyntaxResult = {
name: "testAsync"
}
return await testAwaitPromise(res);
// return { name: "testAsync" };
}
export async function testAsyncParam3(id : number, name : string, opts : AsyncOptions) : Promise<SyntaxResult> {
console.log("id", id, "name", name)
if (opts.type == "success") {
opts.success("success");
} else {
opts.fail("fail");
}
opts.complete("complete");
const res : SyntaxResult = {
name: "testUtsAsyncMulitParam"
}
return await testAwaitPromise(res);
// return { name: "testAsync" };
}
export type TestOptions = {
name : string;
callback : (res : string) => void;
name : string;
callback : (res : string) => void;
};
export class Test {
id : number;
name : string;
static type : string = "Test";
constructor(id : number, options : TestOptions) {
this.id = id;
this.name = options.name;
options.callback("Test.constructor");
}
static testClassStaticSyncWithCallback(opts : AsyncOptions) : SyntaxResult {
return testSyncWithCallback(opts);
}
static async testClassStaticAsync(opts : AsyncOptions) : Promise<SyntaxResult> {
const res = await testAsync(opts);
return res;
}
testClassSyncWithCallback(opts : AsyncOptions) : SyntaxResult {
return testSyncWithCallback(opts);
}
async testClassAsync(opts : AsyncOptions) : Promise<SyntaxResult> {
const res = await testAsync(opts);
return res;
}
id : number;
name : string;
static type : string = "Test";
constructor(id : number, options : TestOptions) {
this.id = id;
this.name = options.name;
options.callback("Test.constructor");
}
static testClassStaticSyncWithCallback(opts : AsyncOptions) : SyntaxResult {
return testSyncWithCallback(opts);
}
static async testClassStaticAsync(opts : AsyncOptions) : Promise<SyntaxResult> {
const res = await testAsync(opts);
return res;
}
testClassSyncWithCallback(opts : AsyncOptions) : SyntaxResult {
return testSyncWithCallback(opts);
}
async testClassAsync(opts : AsyncOptions) : Promise<SyntaxResult> {
const res = await testAsync(opts);
return res;
}
}
class RequestTaskImpl implements RequestTask {
url : string
constructor(url : string) {
this.url = url
}
abort() : RequestTask {
return this
}
onCallback(callback : (res : string) => void) {
callback("onCallback")
}
sync(options : SyncOptions) : string {
options.success?.("success")
options.complete?.("success")
return "sync"
}
url : string
constructor(url : string) {
this.url = url
}
abort() : RequestTask {
return this
}
onCallback(callback : (res : string) => void) {
callback("onCallback")
}
sync(options : SyncOptions) : string {
options.success?.("success")
options.complete?.("success")
return "sync"
}
}
export function request(url : string) : RequestTask | null {
return new RequestTaskImpl(url)
}
\ No newline at end of file
return new RequestTaskImpl(url)
}
// #ifdef APP-ANDROID
// #ifdef UNI-APP-X
import KeyEvent from 'android.view.KeyEvent';
import Configuration from 'android.content.res.Configuration';
import Bundle from 'android.os.Bundle';
import Menu from 'android.view.Menu';
import KeyboardShortcutGroup from 'android.view.KeyboardShortcutGroup';
import WindowManager from 'android.view.WindowManager';
import ActionMode from 'android.view.ActionMode';
// export let onCallBackChange: (event: string) => void = (res) => {};
let callback : (eventLog : string) => void = (res) => { };
export function onCallbackChange(fn : (eventLog : string) => void) {
callback = fn
}
export class UTSAcvitiyLifeCycleCallback extends UniActivityLifeCycleCallback {
constructor() {
super()
}
override onCreate(params : UniActivityParams, savedInstanceState : Bundle | null) {
console.log('UTSAcvitiyLifeCycle', 'onCreate', savedInstanceState)
callback('onCreate')
}
override onResume(params : UniActivityParams) {
console.log('UTSAcvitiyLifeCycle', 'onResume', params)
callback('onResume')
}
override onPreResume(params : UniActivityParams) {
console.log('UTSAcvitiyLifeCycle', 'onPreResume', params)
callback('onPreResume')
}
override onStart(params : UniActivityParams) {
console.log('UTSAcvitiyLifeCycle', 'onStart', params)
callback('onStart')
}
override onPreStart(params : UniActivityParams) {
console.log('UTSAcvitiyLifeCycle', 'onPreStart', params)
callback('onPreStart')
}
}
export class UTSAcvitiyKeyEventCallback extends UniActivityKeyEventCallback {
constructor() {
super()
}
override onKeyDown(params : UniActivityParams, keyCode : Int, event : KeyEvent | null) {
console.log('UTSAcvitiyKeyEvent', 'onKeyDown', params, keyCode, '' + event)
callback('onKeyDown')
}
override onPreKeyDown(params : UniActivityParams, keyCode : Int, event : KeyEvent | null) {
console.log('UTSAcvitiyKeyEvent', 'onPreKeyDown', params, keyCode, '' + event)
callback('onPreKeyDown')
}
override onKeyLongPress(params : UniActivityParams, keyCode : Int, event : KeyEvent | null) {
console.log('UTSAcvitiyKeyEvent', 'onKeyLongPress', params, keyCode, '' + event)
callback('onKeyLongPress')
}
override onPreKeyLongPress(params : UniActivityParams, keyCode : Int, event : KeyEvent | null) {
console.log('UTSAcvitiyKeyEvent', 'onPreKeyLongPress', params, keyCode, '' + event)
callback('onPreKeyLongPress')
}
}
export class UTSActivityWindowCallback extends UniActivityWindowCallback {
constructor() {
super()
}
override dispatchPreKeyEvent(params : UniActivityParams, event : KeyEvent | null) {
console.log('UTSActivityWindowCallback', 'dispatchPreKeyEvent', params, '' + event)
callback('dispatchPreKeyEvent')
}
override dispatchKeyEvent(params : UniActivityParams, event : KeyEvent | null) {
console.log('UTSActivityWindowCallback', 'dispatchKeyEvent', params, '' + event)
callback('dispatchKeyEvent')
}
override onWindowAttributesChanged(params : UniActivityParams, attrs : WindowManager.LayoutParams) {
console.log('UTSActivityWindowCallback', 'onWindowAttributesChanged', '' + attrs)
callback('onWindowAttributesChanged')
}
override onAttachedToWindow(params : UniActivityParams) {
console.log('UTSActivityWindowCallback', 'onAttachedToWindow', params)
callback('onAttachedToWindow')
}
override onPanelClosed(params : UniActivityParams, featureId : Int, menu : Menu) {
console.log('UTSActivityWindowCallback', 'onPanelClosed', featureId, menu)
callback('onPanelClosed')
}
override onWindowStartingActionMode(params : UniActivityParams, callback : ActionMode.Callback | null) {
console.log('UTSActivityWindowCallback', 'onWindowStartingActionMode', callback)
callback('onWindowStartingActionMode')
}
override onProvideKeyboardShortcuts(params : UniActivityParams, data : MutableList<KeyboardShortcutGroup> | null, menu : Menu | null, deviceId : Int) {
console.log('UTSActivityWindowCallback', 'onProvideKeyboardShortcuts', data, menu)
callback('onProvideKeyboardShortcuts')
}
override onPreWindowAttributesChanged(params : UniActivityParams, attrs : WindowManager.LayoutParams) {
console.log('UTSActivityWindowCallback', 'onPreWindowAttributesChanged', attrs)
callback('onPreWindowAttributesChanged')
}
override onPrePanelClosed(params : UniActivityParams, featureId : Int, menu : Menu) {
console.log('UTSActivityWindowCallback', 'onPrePanelClosed', featureId, menu)
callback('onPrePanelClosed')
}
}
export class UTSActivityCallback extends UniActivityCallback {
constructor() {
super()
}
override onBackPressed(params : UniActivityParams) {
console.log('UTSActivityCallback', 'onBackPressed', params)
callback('onBackPressed')
}
override onPreBackPressed(params : UniActivityParams) {
console.log('UTSActivityCallback', 'onPreBackPressed', params)
callback('onPreBackPressed')
}
override onRequestPermissionsResult(params : UniActivityParams, requestCode : Int, permissions : MutableList<String>, grantResults : IntArray) {
console.log('UTSActivityCallback', 'onRequestPermissionsResult', params)
callback('onRequestPermissionsResult')
}
}
export class UTSActivityComponentCallback extends UniActivityComponentCallback {
constructor() {
super()
}
override onConfigurationChanged(params : UniActivityParams, newConfig : Configuration) {
console.log('UTSActivityComponentCallback', 'onConfigurationChanged', params, '' + newConfig)
callback('onConfigurationChanged')
}
override onPreConfigurationChanged(params : UniActivityParams, newConfig : Configuration) {
console.log('UTSActivityComponentCallback', 'onPreConfigurationChanged', params, '' + newConfig)
callback('onPreConfigurationChanged')
}
}
// #endif
// #endif
\ No newline at end of file
......@@ -63,6 +63,19 @@ export function testDate() : Result {
expect(event2.toDateString()).toEqual("Thu Jan 09 2014");
// #endif
})
test('newDateTest', () => {
// #ifdef APP-ANDROID
expect(new Date("2024/5/1").toString()).toEqual("Wed May 01 2024 00:00:00 GMT+0800");
expect(new Date("2024/5/1 10:00:00").toString()).toEqual("Wed May 01 2024 10:00:00 GMT+0800");
expect(new Date("2024-05-01 10:00:00").toString()).toEqual("Wed May 01 2024 10:00:00 GMT+0800");
expect(new Date("2024-05-01 11:00").toString()).toEqual("Wed May 01 2024 11:00:00 GMT+0800");
expect(new Date("2024/05/01 12:00").toString()).toEqual("Wed May 01 2024 12:00:00 GMT+0800");
expect(new Date("2024-5-1 10:00").toString()).toEqual("Wed May 01 2024 10:00:00 GMT+0800");
expect(new Date("2024/5/1 10:00").toString()).toEqual("Wed May 01 2024 10:00:00 GMT+0800");
// #endif
})
test('getDate', () => {
......@@ -87,7 +100,10 @@ export function testDate() : Result {
// subsequent millisecond (month boundary)
expect(new Date(2016, 1, 29, 23, 59, 59, 1000).getDate()).toEqual(1);
// #ifndef WEB
// safari 15不支持此格式的日期字符串
expect(Date.parse("2024-01-09 22:00:00")).toEqual(1704808800000);
// #endif
})
test('getDay', () => {
......
......@@ -9,6 +9,11 @@ export function testError(): Result {
expect((e as Error).message).toEqual("Whoops!");
}
})
test('UniError', () => {
expect(new UniError().message).toEqual('')
expect(new UniError('Whoops!').message).toEqual('Whoops!')
})
// test('name', () => {
// const e = new Error("Malformed input"); // e.name is 'Error'
// e.name = "ParseError";
......
......@@ -3,6 +3,22 @@ import { describe, test, expect, Result } from './tests.uts'
export function testGlobal(): Result {
return describe("Global", () => {
test('setInterval', () => {
// #ifdef APP-ANDROID
let aCount = 0
let taskId = setInterval(function(){
aCount += 1
},0)
setTimeout(function(){
console.log(aCount)
console.log(taskId)
clearInterval(taskId)
expect(aCount > 10).toEqual(true);
},200)
// #endif
})
test('parseInt', () => {
expect(parseInt("123.456")).toEqual(123);
expect(parseInt("123")).toEqual(123);
......
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;
}
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<UTSJSONObject>(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<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', () => {
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<UserJSON>(json1);
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', () => {
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]);
const json3 = `[{"name":"John","id":"30"},{"name":"jack","id":"21"}]`;
const array3 = JSON.parseArray<UTSJSONObject>(json3);
// expect((array3![0])["name"]).toEqual("John");
})
test('stringify', () => {
const obj = { name: 'John', age: 30 };
const json = JSON.stringify(obj);
// expect(json).toEqual('{"name":"John","age":30}');
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}');
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
* 部分出错过的示例场景
*/
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
})
// 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>(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)!
//console.warn('params', JSON.stringify(params))
//expect(JSON.stringify(params)).toEqual('{"method":"reLaunch","args":[{"url":"/pages/index/index"}]}')
class Stage {
$m : string
$p : Array<any>
constructor() {
this.$m = 'test'
this.$p = ['type']
}
}
const obj22 = {
data: [new Stage()] as Array<any>
} as UTSJSONObject
console.log(JSON.stringify(obj22))
// expect(JSON.stringify(obj22)).toEqual('{"data":[{}]}')
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")
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;
}
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<UTSJSONObject>(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<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', () => {
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<UserJSON>(json1);
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', () => {
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]);
const json3 = `[{"name":"John","id":"30"},{"name":"jack","id":"21"}]`;
const array3 = JSON.parseArray<UTSJSONObject>(json3);
// expect((array3![0])["name"]).toEqual("John");
})
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<UTSJSONObject>(JSON.stringify(data2))!, JSON.parse<UTSJSONObject>(JSON.stringify(data1))!) as UTSJSONObject;
const innerObj = obj.getJSON("aa.bb")
expect(innerObj instanceof UTSJSONObject).toEqual(true);
// #endif
})
test('stringify', () => {
const obj = { name: 'John', age: 30 };
const json = JSON.stringify(obj);
// expect(json).toEqual('{"name":"John","age":30}');
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}');
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
* 部分出错过的示例场景
*/
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
})
// 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>(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)!
//console.warn('params', JSON.stringify(params))
//expect(JSON.stringify(params)).toEqual('{"method":"reLaunch","args":[{"url":"/pages/index/index"}]}')
class Stage {
$m : string
$p : Array<any>
constructor() {
this.$m = 'test'
this.$p = ['type']
}
}
const obj22 = {
data: [new Stage()] as Array<any>
} as UTSJSONObject
console.log(JSON.stringify(obj22))
// expect(JSON.stringify(obj22)).toEqual('{"data":[{}]}')
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")
//console.log(JSON.stringify(a));
const map = {
a: 1
}.toMap()
expect(map.get('a')).toEqual(1)
})
})
expect(map.get('a')).toEqual(1)
})
test('parse Map', () => {
type A = {
num: number,
}
const map = JSON.parse<Map<string, A>>(`{"a": {"num": 1}}`)
// #ifndef APP-IOS
expect(map instanceof Map).toEqual(true)
// #endif
expect(map?.get('a')?.num).toEqual(1)
})
})
}
\ No newline at end of file
因为 它太大了无法显示 source diff 。你可以改为 查看blob
......@@ -109,6 +109,8 @@ export function testMath(): Result {
expect(Math.ceil(4)).toEqual(4);
expect(Math.ceil(7.004)).toEqual(8);
expect(Math.ceil(-7.004)).toEqual(-7);
expect(Math.ceil(37110233000.223)).toEqual(37110233001);
expect(Math.ceil(-37110233000.223)).toEqual(-37110233000);
})
test('clz32', () => {
expect(Math.clz32(1)).toEqual(31);
......@@ -141,6 +143,8 @@ export function testMath(): Result {
expect(Math.floor(5.05)).toEqual(5);
expect(Math.floor(5)).toEqual(5);
expect(Math.floor(-5.05)).toEqual(-6);
expect(Math.floor(37110233000.223)).toEqual(37110233000);
expect(Math.floor(-37110233000.223)).toEqual(-37110233001);
})
test('fround', () => {
expect(Math.fround(1.5)).toEqual(1.5);
......@@ -236,10 +240,12 @@ export function testMath(): Result {
expect(Math.trunc(42.84)).toEqual(42);
expect(Math.trunc(0.123)).toEqual(0);
})
test('round', () => {
expect(Math.round(0.9)).toEqual(1);
expect(Math.round(5.95)).toEqual(6);
expect(Math.round(-5.05)).toEqual(-5);
})
test('round', () => {
expect(Math.round(0.9)).toEqual(1);
expect(Math.round(5.95)).toEqual(6);
expect(Math.round(-5.05)).toEqual(-5);
expect(Math.round(37110233000.223)).toEqual(37110233000);
expect(Math.round(-37110233000.223)).toEqual(-37110233000);
})
})
}
......@@ -224,6 +224,8 @@ export function testRegExp(): Result {
const result8 = pattern8.exec('https://example.org')!;
expect(result8[0]).toEqual('https://example.org');
// #ifndef WEB
// 目前的测试环境safari版本为15,不支持?<
const pattern9 = /(?<=@)\w+/;
const result9 = pattern9.exec('Email: john@example.com')!;
expect(result9[0]).toEqual('example');
......@@ -231,6 +233,7 @@ export function testRegExp(): Result {
const pattern10 = /(?<!@)\w+/;
const result10 = pattern10.exec('Username: john')!;
expect(result10[0]).toEqual('Username');
// #endif
const CHUNK_REGEXP =
......
import { describe, test, expect, expectNumber, Result } from './tests.uts'
export function testUTSJSONObject() : Result {
return describe("utsjsonobject", () => {
test('keys', () => {
// #ifdef APP-ANDROID
let obj = {
name:"zhangsan",
age:11
}
expect(UTSJSONObject.keys(obj).size).toEqual(2);
console.log(UTSJSONObject.keys(obj))
// #endif
})
test('assign-notype', () => {
// #ifdef APP-ANDROID
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = UTSJSONObject.assign(target, source);
expect(returnedTarget!.toMap().size).toEqual(3);
console.log(returnedTarget)
// #endif
})
test('assign-withtype', () => {
// #ifdef APP-ANDROID
type User = {
a:number
b:number
}
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = UTSJSONObject.assign<User>(target, source);
expect(returnedTarget!.a).toEqual(1);
console.log(returnedTarget)
// #endif
})
})
}
\ No newline at end of file
import { describe, test, expect, expectNumber, Result } from './tests.uts'
function obtainInnerObject(obj:Any | null):UTSJSONObject{
let jsonStr = console.getLogV2(obj).slice(19,-17)
let a = JSON.parseArray(jsonStr)![0]
return a as UTSJSONObject
}
export function testConsole() : Result {
return describe("log", () => {
test('log-native-obj', () => {
// #ifdef APP-ANDROID
expect(obtainInnerObject(0.9).get("type")).toEqual("Double");
expect(obtainInnerObject(0.9).get("subType")).toEqual("number");
expect(obtainInnerObject(0.9).get("value")).toEqual("0.9");
// #endif
}
)
})
}
\ No newline at end of file
......@@ -3,7 +3,10 @@ import { testDate } from './Date.uts'
import { testString } from './String.uts'
import { testError } from './Error.uts'
import { testKeyWord } from './KeyWord.uts'
import { testJSON } from './JSON.uts'
import { testJSON } from './JSON.uts'
import { testJSONLarge } from './JSON_large.uts'
import { testUTSJSONObject } from './UTSJSONObject.uts'
import { testConsole } from './console.uts'
import { testNumber } from './Number.uts'
import { testMap } from './Map.uts'
import { testSet } from './Set.uts'
......@@ -31,14 +34,17 @@ export function runTests() : UTSJSONObject {
const KeyWordRes = testKeyWord();
const ForLoopRes = testForLoop();
const GlobalRes = testGlobal();
const TypeRes = testType();
const TypeRes = testType();
const JSONLargeRes = testJSONLarge();
const consoleRes = testConsole();
const UTSJSONObjectRes = testUTSJSONObject();
return {
Array: ArrayRes,
Date: DateRes,
String: StringRes,
Error: ErrorRes,
Json: JsonRes,
Json: JsonRes,
JSONLarge:JSONLargeRes,
Number: NumberRes,
Map: MapRes,
Set: SetRes,
......@@ -48,6 +54,8 @@ export function runTests() : UTSJSONObject {
KeyWord: KeyWordRes,
ForLoop: ForLoopRes,
Global: GlobalRes,
Type: TypeRes
Type: TypeRes,
console:consoleRes,
UTSJSONObject:UTSJSONObjectRes
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册