diff --git a/build-profile.json5 b/build-profile.json5
index ec555ee5bb89d82226cf4cbd05c14269796b6aeb..dc712a80d04d5f916542e44793998c2e000d1283 100644
--- a/build-profile.json5
+++ b/build-profile.json5
@@ -1,14 +1,14 @@
{
"app": {
"signingConfigs": [],
- "compileSdkVersion": 9,
- "compatibleSdkVersion": 9,
"products": [
{
+ "compileSdkVersion": 11,
+ "compatibleSdkVersion": 11,
"name": "default",
- "signingConfig": "default",
+ "signingConfig": "default"
}
- ]
+ ],
},
"modules": [
{
diff --git a/common/BuildProfile.ets b/common/BuildProfile.ets
new file mode 100644
index 0000000000000000000000000000000000000000..3a501e5ddee8ea6d28961648fc7dd314a5304bd4
--- /dev/null
+++ b/common/BuildProfile.ets
@@ -0,0 +1,17 @@
+/**
+ * Use these variables when you tailor your ArkTS code. They must be of the const type.
+ */
+export const HAR_VERSION = '1.0.0';
+export const BUILD_MODE_NAME = 'debug';
+export const DEBUG = true;
+export const TARGET_NAME = 'default';
+
+/**
+ * BuildProfile Class is used only for compatibility purposes.
+ */
+export default class BuildProfile {
+ static readonly HAR_VERSION = HAR_VERSION;
+ static readonly BUILD_MODE_NAME = BUILD_MODE_NAME;
+ static readonly DEBUG = DEBUG;
+ static readonly TARGET_NAME = TARGET_NAME;
+}
\ No newline at end of file
diff --git a/common/build-profile.json5 b/common/build-profile.json5
index 35dff6d53cb3a241f8de4fb68bd01d38ade0f108..7374b5c13faa1f45347034d15c09cbc09a8ab154 100644
--- a/common/build-profile.json5
+++ b/common/build-profile.json5
@@ -1,5 +1,17 @@
{
"apiType": "stageMode",
"buildOption": {
- }
+ },
+ "buildOptionSet": [
+ {
+ "name": "release",
+ "arkOptions": {
+ "obfuscation": {
+ "ruleOptions": {
+ "enable": false,
+ }
+ }
+ }
+ },
+ ]
}
diff --git a/common/oh-package.json5 b/common/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..3159c134e8893daf7afdf1dc73ed683c7ee24fc2
--- /dev/null
+++ b/common/oh-package.json5
@@ -0,0 +1,12 @@
+{
+ "license": "ISC",
+ "types": "",
+ "devDependencies": {},
+ "name": "@ohos/common",
+ "description": "a npm package which contains arkUI2.0 page",
+ "ohos": {
+ "org": ""
+ },
+ "main": "index.ets",
+ "version": "1.0.0",
+}
diff --git a/common/package.json b/common/package.json
index 6845131bfa2ddc9998b03c56d12c85edc1a861e2..dfbf6f7a0611aa4c4fa5f81337f132a4f4a9a694 100644
--- a/common/package.json
+++ b/common/package.json
@@ -10,5 +10,7 @@
"main": "src/main/ets/components/MainPage/MainPage.ets",
"repository": {},
"version": "1.0.0",
- "dependencies": {}
+ "dependencies": {
+ "@ohos/hap": "^3.0.0"
+ }
}
diff --git a/common/src/main/ets/utils/Util.ets b/common/src/main/ets/utils/Util.ets
index 2887d8f9f4238430c8934332067eab7c79c826c6..d7ff0707252d2bb0d89e37c144e7fdfab82fb52e 100644
--- a/common/src/main/ets/utils/Util.ets
+++ b/common/src/main/ets/utils/Util.ets
@@ -28,12 +28,12 @@ export default class Util {
let timeStr = "";
let hour = Math.floor(timestamp % (24 * 60 * 60 * 1000) / (60 * 60 * 1000));
if (hasHour || hour > 0) {
- timeStr += this.addZero(hour) + ":";
+ timeStr += Util.addZero(hour) + ":";
}
let min = Math.floor(timestamp % (60 * 60 * 1000) / (60 * 1000));
- timeStr += this.addZero(min) + ":";
+ timeStr += Util.addZero(min) + ":";
let sec = Math.floor(timestamp % (60 * 1000) / 1000);
- timeStr += this.addZero(sec);
+ timeStr += Util.addZero(sec);
return timeStr;
}
@@ -49,15 +49,15 @@ export default class Util {
let timeStr = "";
let hour = Math.floor(timestamp % (24 * 60 * 60 * 1000) / (60 * 60 * 1000));
if (hour > 0) {
- timeStr += this.addZero(hour) + ":";
+ timeStr += Util.addZero(hour) + ":";
}
let min = Math.floor(timestamp % (60 * 60 * 1000) / (60 * 1000));
- timeStr += this.addZero(min) + ":";
+ timeStr += Util.addZero(min) + ":";
let sec = Math.floor(timestamp % (60 * 1000) / 1000);
- timeStr += this.addZero(sec);
+ timeStr += Util.addZero(sec);
if (hour < 1) {
let mSec = Math.floor(timestamp % 1000 / 10);
- timeStr += "." + this.addZero(mSec);
+ timeStr += "." + Util.addZero(mSec);
}
return timeStr;
}
@@ -69,7 +69,7 @@ export default class Util {
*/
static getDateFormat(date: number): string {
let nowDate = new Date(date);
- return nowDate.getFullYear() + "/" + this.addZero(nowDate.getMonth() + 1) + "/" + this.addZero(nowDate.getDate());
+ return nowDate.getFullYear() + "/" + Util.addZero(nowDate.getMonth() + 1) + "/" + Util.addZero(nowDate.getDate());
}
/**
@@ -79,7 +79,7 @@ export default class Util {
*/
static getTimeFormat(date: number): string {
let nowDate = new Date(date);
- return this.addZero(nowDate.getHours()) + ":" + this.addZero(nowDate.getMinutes()) + ":" + this.addZero(nowDate.getSeconds());
+ return Util.addZero(nowDate.getHours()) + ":" + Util.addZero(nowDate.getMinutes()) + ":" + Util.addZero(nowDate.getSeconds());
}
/**
@@ -87,7 +87,7 @@ export default class Util {
*/
static getDate(): string {
let nowDate = new Date();
- return nowDate.getFullYear() + this.addZero(nowDate.getMonth() + 1) + this.addZero(nowDate.getDate());
+ return nowDate.getFullYear() + Util.addZero(nowDate.getMonth() + 1) + Util.addZero(nowDate.getDate());
}
/**
@@ -95,7 +95,7 @@ export default class Util {
*/
static getTime(): string {
let nowDate = new Date();
- return this.addZero(nowDate.getHours()) + this.addZero(nowDate.getMinutes()) + this.addZero(nowDate.getSeconds());
+ return Util.addZero(nowDate.getHours()) + Util.addZero(nowDate.getMinutes()) + Util.addZero(nowDate.getSeconds());
}
/**
diff --git a/feature/recorder/BuildProfile.ets b/feature/recorder/BuildProfile.ets
new file mode 100644
index 0000000000000000000000000000000000000000..3a501e5ddee8ea6d28961648fc7dd314a5304bd4
--- /dev/null
+++ b/feature/recorder/BuildProfile.ets
@@ -0,0 +1,17 @@
+/**
+ * Use these variables when you tailor your ArkTS code. They must be of the const type.
+ */
+export const HAR_VERSION = '1.0.0';
+export const BUILD_MODE_NAME = 'debug';
+export const DEBUG = true;
+export const TARGET_NAME = 'default';
+
+/**
+ * BuildProfile Class is used only for compatibility purposes.
+ */
+export default class BuildProfile {
+ static readonly HAR_VERSION = HAR_VERSION;
+ static readonly BUILD_MODE_NAME = BUILD_MODE_NAME;
+ static readonly DEBUG = DEBUG;
+ static readonly TARGET_NAME = TARGET_NAME;
+}
\ No newline at end of file
diff --git a/feature/recorder/oh-package-lock.json5 b/feature/recorder/oh-package-lock.json5
new file mode 100644
index 0000000000000000000000000000000000000000..71fb2aa27ea03ee139d0c1365fbfd5ab52c7931d
--- /dev/null
+++ b/feature/recorder/oh-package-lock.json5
@@ -0,0 +1,18 @@
+{
+ "meta": {
+ "stableOrder": true
+ },
+ "lockfileVersion": 3,
+ "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
+ "specifiers": {
+ "@ohos/common@../../common": "@ohos/common@../../common"
+ },
+ "packages": {
+ "@ohos/common@../../common": {
+ "name": "@ohos/common",
+ "version": "1.0.0",
+ "resolved": "../../common",
+ "registryType": "local"
+ }
+ }
+}
\ No newline at end of file
diff --git a/feature/recorder/oh-package.json5 b/feature/recorder/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..c395a2849c8e98e829d405d584bcb87dc6cfa72b
--- /dev/null
+++ b/feature/recorder/oh-package.json5
@@ -0,0 +1,13 @@
+{
+ "license": "ISC",
+ "types": "",
+ "devDependencies": {
+ "@ohos/common": "file:../../common"
+ },
+ "name": "@ohos/recorder",
+ "description": "a npm package which contains arkUI2.0 page",
+ "main": "index.ets",
+ "version": "1.0.0",
+ "dynamicDependencies": {},
+ "dependencies": {}
+}
diff --git a/feature/recorder/oh_modules/@ohos/common/.gitignore b/feature/recorder/oh_modules/@ohos/common/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4f9a973815d0b5e49bc8547681a6b4bc7a178d12
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/.gitignore
@@ -0,0 +1,3 @@
+/node_modules
+/.preview
+/build
\ No newline at end of file
diff --git a/feature/recorder/oh_modules/@ohos/common/BuildProfile.ets b/feature/recorder/oh_modules/@ohos/common/BuildProfile.ets
new file mode 100644
index 0000000000000000000000000000000000000000..3a501e5ddee8ea6d28961648fc7dd314a5304bd4
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/BuildProfile.ets
@@ -0,0 +1,17 @@
+/**
+ * Use these variables when you tailor your ArkTS code. They must be of the const type.
+ */
+export const HAR_VERSION = '1.0.0';
+export const BUILD_MODE_NAME = 'debug';
+export const DEBUG = true;
+export const TARGET_NAME = 'default';
+
+/**
+ * BuildProfile Class is used only for compatibility purposes.
+ */
+export default class BuildProfile {
+ static readonly HAR_VERSION = HAR_VERSION;
+ static readonly BUILD_MODE_NAME = BUILD_MODE_NAME;
+ static readonly DEBUG = DEBUG;
+ static readonly TARGET_NAME = TARGET_NAME;
+}
\ No newline at end of file
diff --git a/feature/recorder/oh_modules/@ohos/common/build-profile.json5 b/feature/recorder/oh_modules/@ohos/common/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..7374b5c13faa1f45347034d15c09cbc09a8ab154
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/build-profile.json5
@@ -0,0 +1,17 @@
+{
+ "apiType": "stageMode",
+ "buildOption": {
+ },
+ "buildOptionSet": [
+ {
+ "name": "release",
+ "arkOptions": {
+ "obfuscation": {
+ "ruleOptions": {
+ "enable": false,
+ }
+ }
+ }
+ },
+ ]
+}
diff --git a/feature/recorder/oh_modules/@ohos/common/hvigorfile.js b/feature/recorder/oh_modules/@ohos/common/hvigorfile.js
new file mode 100644
index 0000000000000000000000000000000000000000..42ed4b4a54a873e2b53441556aae93fab24b794f
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/hvigorfile.js
@@ -0,0 +1,3 @@
+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
+module.exports = require('@ohos/hvigor-ohos-plugin').harTasks
+
diff --git a/feature/recorder/oh_modules/@ohos/common/index.ets b/feature/recorder/oh_modules/@ohos/common/index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..af9c605b34eec7395760f18018aea72ecbd1e703
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/index.ets
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { default as ConfigData } from './src/main/ets/utils/ConfigData'
+
+export { default as Util } from './src/main/ets/utils/Util'
+
+export { default as LogUtil } from './src/main/ets/utils/LogUtil'
diff --git a/feature/recorder/oh_modules/@ohos/common/oh-package.json5 b/feature/recorder/oh_modules/@ohos/common/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..3159c134e8893daf7afdf1dc73ed683c7ee24fc2
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/oh-package.json5
@@ -0,0 +1,12 @@
+{
+ "license": "ISC",
+ "types": "",
+ "devDependencies": {},
+ "name": "@ohos/common",
+ "description": "a npm package which contains arkUI2.0 page",
+ "ohos": {
+ "org": ""
+ },
+ "main": "index.ets",
+ "version": "1.0.0",
+}
diff --git a/feature/recorder/oh_modules/@ohos/common/package.json b/feature/recorder/oh_modules/@ohos/common/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..dfbf6f7a0611aa4c4fa5f81337f132a4f4a9a694
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/package.json
@@ -0,0 +1,16 @@
+{
+ "license": "ISC",
+ "types": "",
+ "devDependencies": {},
+ "name": "@ohos/common",
+ "description": "a npm package which contains arkUI2.0 page",
+ "ohos": {
+ "org": ""
+ },
+ "main": "src/main/ets/components/MainPage/MainPage.ets",
+ "repository": {},
+ "version": "1.0.0",
+ "dependencies": {
+ "@ohos/hap": "^3.0.0"
+ }
+}
diff --git a/feature/recorder/oh_modules/@ohos/common/src/main/ets/utils/ConfigData.ets b/feature/recorder/oh_modules/@ohos/common/src/main/ets/utils/ConfigData.ets
new file mode 100644
index 0000000000000000000000000000000000000000..728136a483d65992eec74b7fd766c0e7792b66cb
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/src/main/ets/utils/ConfigData.ets
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export class ConfigData {
+ WH_100_100 = '100%';
+ WH_50_100 = '50%';
+ WH_40_100 = '40%';
+ WH_20_100 = '20%';
+}
+
+let configData = new ConfigData();
+
+export default configData as ConfigData;
\ No newline at end of file
diff --git a/feature/recorder/oh_modules/@ohos/common/src/main/ets/utils/LogUtil.ts b/feature/recorder/oh_modules/@ohos/common/src/main/ets/utils/LogUtil.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bbead9dd9befd61c6caee01842404061533ef8aa
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/src/main/ets/utils/LogUtil.ts
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import HiLog from "@ohos.hilog";
+
+const DOMAIN = 0x0500;
+const TAG = "[Recorder]";
+
+/**
+ * log package tool class
+ */
+export default class LogUtil {
+ static debug(msg): void {
+ HiLog.debug(DOMAIN, TAG, msg);
+ }
+
+ static log(msg): void {
+ HiLog.info(DOMAIN, TAG, msg);
+ }
+
+ static info(msg): void {
+ HiLog.info(DOMAIN, TAG, msg);
+ }
+
+ static warn(msg): void {
+ HiLog.warn(DOMAIN, TAG, msg);
+ }
+
+ static error(msg): void {
+ HiLog.error(DOMAIN, TAG, msg);
+ }
+}
\ No newline at end of file
diff --git a/feature/recorder/oh_modules/@ohos/common/src/main/ets/utils/Util.ets b/feature/recorder/oh_modules/@ohos/common/src/main/ets/utils/Util.ets
new file mode 100644
index 0000000000000000000000000000000000000000..d7ff0707252d2bb0d89e37c144e7fdfab82fb52e
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/src/main/ets/utils/Util.ets
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default class Util {
+
+ /**
+ * Time format is converted to seconds
+ *
+ * @param timestamp
+ * @param hasHour
+ */
+ static timeFormat(timestamp: number, hasHour: boolean = true): string {
+ if (timestamp < 0) {
+ return "";
+ }
+ let timeStr = "";
+ let hour = Math.floor(timestamp % (24 * 60 * 60 * 1000) / (60 * 60 * 1000));
+ if (hasHour || hour > 0) {
+ timeStr += Util.addZero(hour) + ":";
+ }
+ let min = Math.floor(timestamp % (60 * 60 * 1000) / (60 * 1000));
+ timeStr += Util.addZero(min) + ":";
+ let sec = Math.floor(timestamp % (60 * 1000) / 1000);
+ timeStr += Util.addZero(sec);
+ return timeStr;
+ }
+
+ /**
+ * Time format is converted to milliseconds
+ *
+ * @param timestamp
+ */
+ static timeFormatMs(timestamp: number): string {
+ if (timestamp <= 0) {
+ return "00:00.00";
+ }
+ let timeStr = "";
+ let hour = Math.floor(timestamp % (24 * 60 * 60 * 1000) / (60 * 60 * 1000));
+ if (hour > 0) {
+ timeStr += Util.addZero(hour) + ":";
+ }
+ let min = Math.floor(timestamp % (60 * 60 * 1000) / (60 * 1000));
+ timeStr += Util.addZero(min) + ":";
+ let sec = Math.floor(timestamp % (60 * 1000) / 1000);
+ timeStr += Util.addZero(sec);
+ if (hour < 1) {
+ let mSec = Math.floor(timestamp % 1000 / 10);
+ timeStr += "." + Util.addZero(mSec);
+ }
+ return timeStr;
+ }
+
+ /**
+ * Gets the date at the specified time
+ *
+ * @param date
+ */
+ static getDateFormat(date: number): string {
+ let nowDate = new Date(date);
+ return nowDate.getFullYear() + "/" + Util.addZero(nowDate.getMonth() + 1) + "/" + Util.addZero(nowDate.getDate());
+ }
+
+ /**
+ * Gets the hour, minute and second of the specified time
+ *
+ * @param date
+ */
+ static getTimeFormat(date: number): string {
+ let nowDate = new Date(date);
+ return Util.addZero(nowDate.getHours()) + ":" + Util.addZero(nowDate.getMinutes()) + ":" + Util.addZero(nowDate.getSeconds());
+ }
+
+ /**
+ * Gets the current time date
+ */
+ static getDate(): string {
+ let nowDate = new Date();
+ return nowDate.getFullYear() + Util.addZero(nowDate.getMonth() + 1) + Util.addZero(nowDate.getDate());
+ }
+
+ /**
+ * Gets the hour, minute and second of the current time
+ */
+ static getTime(): string {
+ let nowDate = new Date();
+ return Util.addZero(nowDate.getHours()) + Util.addZero(nowDate.getMinutes()) + Util.addZero(nowDate.getSeconds());
+ }
+
+ /**
+ * If the number is less than 10, add "0".
+ *
+ * @param num
+ */
+ static addZero(num: number): string{
+ return (num < 10 ? "0" + num : num).toString();
+ }
+}
\ No newline at end of file
diff --git a/feature/recorder/oh_modules/@ohos/common/src/main/module.json5 b/feature/recorder/oh_modules/@ohos/common/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..56a91a87ba3ea303b57e4b8e5f405e9d6d2a800a
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/src/main/module.json5
@@ -0,0 +1,11 @@
+{
+ "module": {
+ "name": "common",
+ "type": "har",
+ "deviceTypes": [
+ "default",
+ "tablet"
+ ],
+ "uiSyntax": "ets"
+ }
+}
diff --git a/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/element/color.json b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..ffe7272ac3029e44fd8fe56844ac7a59808be8a2
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/element/color.json
@@ -0,0 +1,32 @@
+{
+ "color": [
+ {
+ "name": "white",
+ "value": "#FFFFFF"
+ },
+ {
+ "name": "background_color",
+ "value": "#F1F3F5"
+ },
+ {
+ "name": "shadow_color",
+ "value": "#11000000"
+ },
+ {
+ "name": "pointer_color",
+ "value": "#007DFF"
+ },
+ {
+ "name": "warn_color",
+ "value": "#FF595A"
+ },
+ {
+ "name": "hint_color",
+ "value": "#007DFF"
+ },
+ {
+ "name": "text_color",
+ "value": "#182431"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/element/string.json b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..2375b2de43748384262b8e07fa36405169d878c8
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/element/string.json
@@ -0,0 +1,56 @@
+{
+ "string": [
+ {
+ "name": "page_show",
+ "value": "page from npm package"
+ },
+ {
+ "name": "title",
+ "value": "录音机"
+ },
+ {
+ "name": "search_recording_files",
+ "value": "搜索录音文件"
+ },
+ {
+ "name": "mark",
+ "value": "标记"
+ },
+ {
+ "name": "pause",
+ "value": "暂停"
+ },
+ {
+ "name": "continue_record",
+ "value": "继续"
+ },
+ {
+ "name": "predict_hint",
+ "value": "预计还能录制10小时以上"
+ },
+ {
+ "name": "delete_hint",
+ "value": "是否删除此条录音?"
+ },
+ {
+ "name": "cancel",
+ "value": "取消"
+ },
+ {
+ "name": "delete",
+ "value": "删除"
+ },
+ {
+ "name": "has_call_hint",
+ "value": "通话状态无法录音"
+ },
+ {
+ "name": "recording_hint",
+ "value": "录音机正在录音"
+ },
+ {
+ "name": "suspend_record_hint",
+ "value": "录音机暂停录音"
+ }
+ ]
+}
diff --git a/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/bg_record.png b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/bg_record.png
new file mode 100644
index 0000000000000000000000000000000000000000..41c12ccb5bb90cd9c05508690ca0b88f33e96008
Binary files /dev/null and b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/bg_record.png differ
diff --git a/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_back.svg b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_back.svg
new file mode 100644
index 0000000000000000000000000000000000000000..6f7f039226e90d3ef91b0e83c4ad29236858e868
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_back.svg
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_add.svg b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_add.svg
new file mode 100644
index 0000000000000000000000000000000000000000..3ec94e4b1e5f198844f5136dc14c9ff00ab95887
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_add.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_enhance.svg b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_enhance.svg
new file mode 100644
index 0000000000000000000000000000000000000000..14a0ba5bbea05082e4659a124dc89b79f523509b
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_enhance.svg
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_mark.svg b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_mark.svg
new file mode 100644
index 0000000000000000000000000000000000000000..330eda737a418114cc3389b4c14cbcada67ec5e9
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_mark.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_play.svg b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_play.svg
new file mode 100644
index 0000000000000000000000000000000000000000..4a6c56994bd7736e81307833789775d51b71cf6c
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_play.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_record.svg b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_record.svg
new file mode 100644
index 0000000000000000000000000000000000000000..c8f7906490d4e4ae103cf1d35fd3e5c4c55f27f0
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_record.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_stop.svg b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_stop.svg
new file mode 100644
index 0000000000000000000000000000000000000000..02964494e7ad6466ce03c368befe5a7e3c1ed01b
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_stop.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_suspend.svg b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_suspend.svg
new file mode 100644
index 0000000000000000000000000000000000000000..bf6f0ea2eabe25b77ef0bed04d52cb1e6ac6bb0b
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_suspend.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_play.svg b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_play.svg
new file mode 100644
index 0000000000000000000000000000000000000000..34c0e947768885c982a4031b2df92c1fe7b014ab
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_play.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_search.svg b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_search.svg
new file mode 100644
index 0000000000000000000000000000000000000000..1b2a8aa35dc2c2ea6b47fad1fdfe319947701b43
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_search.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_stop.svg b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_stop.svg
new file mode 100644
index 0000000000000000000000000000000000000000..2b7ceaa1d1b8a10b1b18f0a1515477874df4b357
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_stop.svg
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/public_more.svg b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/public_more.svg
new file mode 100644
index 0000000000000000000000000000000000000000..400c3ef1abe1ebe1b0637b20c1c4b9711812b41e
--- /dev/null
+++ b/feature/recorder/oh_modules/@ohos/common/src/main/resources/base/media/public_more.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/feature/recorder/src/main/ets/controller/AudioController.ets b/feature/recorder/src/main/ets/controller/AudioController.ets
index 81247180eeff1ff8ad64186231295024a31c279e..2b1cae60bf5f1691912519eeb7df29fd37263f18 100644
--- a/feature/recorder/src/main/ets/controller/AudioController.ets
+++ b/feature/recorder/src/main/ets/controller/AudioController.ets
@@ -16,6 +16,7 @@
import mediaLibrary from '@ohos.multimedia.mediaLibrary';
import media from '@ohos.multimedia.media';
import { LogUtil } from '@ohos/common';
+import { BusinessError, Callback } from '@ohos.base'
export enum AudioState {
/**
@@ -36,24 +37,23 @@ const NOTIFY_INTERVAL_MS = 50;
const TAG = "AudioController : ";
export class AudioController {
- private audioPlayer: media.AudioPlayer = undefined;
- private state: AudioState = AudioState.IDLE;
- private playFile: mediaLibrary.FileAsset = undefined;
+ private audioPlayer?: media.AVPlayer;
+ private state: string = 'idle';
+ private playFile: string = '';
private dataLoad: boolean = false;
- private finishListener: () => void = undefined;
private currentTimeMs: number = 0;
private intervalId: number = -1;
- private timeUpdateListener: (currentTimeMs: number) => void = undefined;
- private stateUpdateListener: (AudioState) => void = undefined;
+ private timeUpdateListener?: Callback;
+ private stateUpdateListener?: Callback;
/**
* Set the time update listener
*
* @param listener
*/
- public setTimeUpdateListener(listener: (currentTimeMs: number) => void) {
+ public setTimeUpdateListener(tag: string, timeUpdateListener: Callback): void {
LogUtil.info(`${TAG} setTimeUpdateListener`);
- this.timeUpdateListener = listener;
+ this.timeUpdateListener = timeUpdateListener;
}
/**
@@ -61,9 +61,9 @@ export class AudioController {
*
* @param listener
*/
- public setStateUpdateListener(listener: (AudioState) => void) {
+ public setStateUpdateListener(tag: string, setStateUpdateListener: Callback): void {
LogUtil.info(`${TAG} setStateUpdateListener`);
- this.stateUpdateListener = listener;
+ this.stateUpdateListener = setStateUpdateListener;
}
/**
@@ -91,70 +91,54 @@ export class AudioController {
* @param playSrc
* @param callback
*/
- initAudioPlayer(playSrc: mediaLibrary.FileAsset, callback: () => void) {
+ async initAudioPlayer(playSrc: string, callback: () => void) {
LogUtil.info(`${TAG} initAudioPlayer`);
this.playFile = playSrc;
this.dataLoad = false;
this.release();
LogUtil.info(`${TAG} createAudioPlayer`);
- this.audioPlayer = media.createAudioPlayer();
- this.audioPlayer.on('dataLoad', () => {
- this.dataLoad = true;
- LogUtil.info(`${TAG} audioPlayer dataLoad success`);
- if (callback) {
- callback();
- }
- })
- this.audioPlayer.on('stop', () => {
- LogUtil.info(`${TAG} audioPlayer stop success`);
- this.release();
- })
- this.audioPlayer.on('error', (error) => {
- LogUtil.error(`${TAG} audioPlayer error. info:${error}`);
- })
- this.audioPlayer.on('timeUpdate', (num) => {
- LogUtil.info(`${TAG} audioPlayer timeUpdate. time:${num}`);
- })
- this.audioPlayer.on('audioInterrupt', (num) => {
- LogUtil.warn(`${TAG} audioPlayer audioInterrupt. time:${num}`);
- })
- this.audioPlayer.on('finish', () => {
- LogUtil.info(`${TAG} audioPlayer finish.`);
- clearInterval(this.intervalId);
- this.intervalId = -1;
- this.state = AudioState.IDLE;
- this.notifyStateChanges();
- })
- LogUtil.info(`${TAG} audioPlayer reset.`)
- this.audioPlayer.reset();
- LogUtil.info(`${TAG} read FileAsset`);
- let fdPath = playSrc.open('r');
- fdPath.then(fdNumber => {
- LogUtil.info(`${TAG} audioPlayer set src`);
- this.audioPlayer.src = `fd://${fdNumber}`;
- });
+ if (!this.audioPlayer) {
+ return;
+ }
+ try {
+ this.audioPlayer = await media.createAVPlayer();
+ } catch (e) {
+ }
+ this.audioPlayer?.on('stateChange', this.stateChangeListener)
}
+ private stateChangeListener = async (state: string, reason: media.StateChangeReason) => {
+ if (!this.audioPlayer) {
+ return;
+ }
+ this.state = state;
+ switch (state) {
+ case 'idle' :
+ break;
+ case 'initialized':
+ break;
+ case 'playing':
+ break;
+ case 'prepared':
+ break;
+ case 'paused':
+ break;
+ case 'completed':
+ break;
+ case 'stopped':
+ case 'released':
+ break;
+ }
+ }
/**
* audioPlayer play
*/
play() {
- if (typeof (this.audioPlayer) != `undefined`) {
- this.audioPlayer.on('play', () => {
- LogUtil.info(`${TAG} audioPlayer play success`);
- this.startTimer();
- });
- if (this.dataLoad) {
- LogUtil.info(`${TAG} audioPlayer play`);
+ try {
+ if (this.audioPlayer) {
this.audioPlayer.play();
- } else {
- this.audioPlayer.on('dataLoad', () => {
- LogUtil.info(`${TAG} audioPlayer dataLoad success`);
- this.dataLoad = true;
- LogUtil.info(`${TAG} audioPlayer play`);
- this.audioPlayer.play();
- });
}
+ } catch (e) {
}
}
@@ -164,7 +148,7 @@ export class AudioController {
* @param timeMs
*/
seek(timeMs: number) {
- if (typeof (this.audioPlayer) != `undefined`) {
+ if (this.audioPlayer) {
LogUtil.info(`${TAG} audioPlayer time to jump. time:` + timeMs);
this.audioPlayer.seek(timeMs);
}
@@ -174,11 +158,7 @@ export class AudioController {
* audioPlayer pause
*/
pause() {
- if (typeof (this.audioPlayer) != `undefined`) {
- this.audioPlayer.on('pause', () => {
- LogUtil.info(`${TAG} audioPlayer pause success`);
- this.stopTimer();
- });
+ if (this.audioPlayer) {
LogUtil.info(`${TAG} audioPlayer pause`);
this.audioPlayer.pause();
}
@@ -188,11 +168,10 @@ export class AudioController {
* audioPlayer stop
*/
stop() {
- if (typeof (this.audioPlayer) != `undefined` && this.state != AudioState.IDLE) {
+ if ((this.audioPlayer) && this.state != 'idle') {
LogUtil.info(`${TAG} audioPlayer stop`);
- this.state = AudioState.IDLE;
- this.notifyStateChanges();
- clearInterval(this.intervalId);
+ this.state = 'idle';
+ this.audioPlayer.release();
this.intervalId = -1;
}
}
@@ -201,47 +180,17 @@ export class AudioController {
* audioPlayer continue play
*/
continuePlay() {
- if (typeof (this.audioPlayer) != `undefined`) {
+ if (this.audioPlayer) {
LogUtil.info(`${TAG} audioPlayer continue play`);
this.audioPlayer.play();
}
}
- /**
- * startTimer
- */
- startTimer() {
- if (this.intervalId != -1) {
- return;
- }
- this.state = AudioState.RUNNING;
- this.notifyStateChanges();
- LogUtil.info(`${TAG} audioPlayer show time update start`);
- this.intervalId = setInterval(() => {
- this.currentTimeMs = this.audioPlayer.currentTime;
- this.notifyTimeChanges();
- }, NOTIFY_INTERVAL_MS);
- }
-
- /**
- * stopTimer
- */
- stopTimer() {
- if (this.intervalId == -1) {
- return;
- }
- this.state = AudioState.PAUSED;
- this.notifyStateChanges();
- LogUtil.info(`${TAG} audioPlayer show time update stop`);
- clearInterval(this.intervalId);
- this.intervalId = -1;
- }
-
/**
* audioPlayer release
*/
release() {
- if (typeof (this.audioPlayer) != `undefined`) {
+ if (this.audioPlayer) {
this.currentTimeMs = 0;
this.notifyTimeChanges();
LogUtil.info(`${TAG} audioPlayer release`);
diff --git a/feature/recorder/src/main/ets/controller/MediaController.ets b/feature/recorder/src/main/ets/controller/MediaController.ets
index 103d07284684cdb6ff8370a1d666290e04515bcd..db8262d36fd8eae29ec262333d9b58a25f0b9b12 100644
--- a/feature/recorder/src/main/ets/controller/MediaController.ets
+++ b/feature/recorder/src/main/ets/controller/MediaController.ets
@@ -21,28 +21,14 @@ import { LogUtil } from '@ohos/common';
const TAG = 'MediaController : ';
-class MediaController {
+export class MediaController {
private mMediaLibrary: mediaLibrary.MediaLibrary = mediaLibrary.getMediaLibrary(globalThis.abilityContext);
- private preferences: data_preferences.Preferences = undefined;
+ private preferences?: data_preferences.Preferences;
constructor() {
this.initPreferences();
}
- /**
- * delete Record
- *
- * @param deleteRecordUri
- * @param callback
- */
- deleteRecord(deleteRecordUri: string, callback: () => void) {
- LogUtil.info(`${TAG} delete Asset. uri: ${deleteRecordUri}`)
- this.mMediaLibrary.deleteAsset(deleteRecordUri).then(() => {
- LogUtil.info(`${TAG} delete Asset successs.`);
- callback();
- });
- }
-
/**
* init Preferences
*/
@@ -65,56 +51,6 @@ class MediaController {
LogUtil.info(`${TAG} save File Duration end.`);
}
}
-
- /**
- * get File Duration from preferences
- *
- * @param name
- */
- async getFileDuration(name: string) {
- LogUtil.info(`${TAG} getFileDuration. fileName : ${name}.`);
- return this.preferences.get(name, 0);
- }
-
- /**
- * query All Audios
- */
- async queryAllAudios() {
- LogUtil.info(`${TAG} queryAllAudios`);
- let fileKeyObj = mediaLibrary.FileKey;
- let fetchOp = {
- selections: `${fileKeyObj.MEDIA_TYPE}=?`,
- selectionArgs: [`${mediaLibrary.MediaType.AUDIO}`],
- }
- LogUtil.info(`${TAG} getFileAssets`);
- const fetchFileResult = await this.mMediaLibrary.getFileAssets(fetchOp);
- LogUtil.info(`${TAG} Assets count : ${fetchFileResult.getCount()}`);
- let result: Array = [];
- if (fetchFileResult.getCount() > 0) {
- let fileAssets = await fetchFileResult.getAllObject();
- for (let i = 0; i < fileAssets.length; i++) {
- let record = new RecordData(fileAssets[i]);
- if (record.duration == 0) {
- await record.getDuration();
- }
- result.push(record);
- }
- }
- return result;
- }
-
- /**
- * create Audio File
- */
- async createAudioFile() {
- LogUtil.info(`${TAG} createAudioFile`);
- this.mMediaLibrary = mediaLibrary.getMediaLibrary(globalThis.abilityContext);
- let displayName = Util.getDate() + "_" + Util.getTime() + ".m4a";
- LogUtil.info(`${TAG} displayName : ${displayName}`);
- let publicPath = await this.mMediaLibrary.getPublicDirectory(mediaLibrary.DirectoryType.DIR_AUDIO);
- LogUtil.info(`${TAG} publicPath : ${publicPath}`);
- return await this.mMediaLibrary.createAsset(mediaLibrary.MediaType.AUDIO, displayName, publicPath);
- }
}
export default new MediaController();
\ No newline at end of file
diff --git a/feature/recorder/src/main/ets/controller/RecordController.ets b/feature/recorder/src/main/ets/controller/RecordController.ets
index 6dc9992f8c07eb8abf1f0e597fbacdb9426f6a8f..ec15a779f0a2967432f910a9e0b4ff8b7cd72c52 100644
--- a/feature/recorder/src/main/ets/controller/RecordController.ets
+++ b/feature/recorder/src/main/ets/controller/RecordController.ets
@@ -16,21 +16,12 @@
import media from '@ohos.multimedia.media';
import { LogUtil } from '@ohos/common';
import Notification from '@ohos.notification';
+import { BusinessError, Callback } from '@ohos.base'
const NOTIFY_INTERVAL_MS = 60;
const NOTIFY_ID = 10023;
const TAG = 'RecordController : ';
-let audioConfig = {
- audioEncodeBitRate: 22050,
- audioSampleRate: 22050,
- numberOfChannels: 2,
- uri: '',
- location: { latitude: 31, longitude: 118 },
- audioEncoderMime: media.CodecMimeType.AUDIO_AAC,
- fileFormat: media.ContainerFormatType.CFT_MPEG_4A,
-}
-
export enum RecordState {
IDLE,
RUNNING,
@@ -41,11 +32,15 @@ export class RecordController {
private beforePauseTime: number = 0;
private startTimestamp: number = 0;
private notifierId: number = -1;
- private state: RecordState = RecordState.PAUSED;
+ private state: string = '';
+ private config?: media.AVRecorderConfig;
+ private openedFileFd?: number;
+ private currentFilePath?: string;
+ private recorderDuration: number = 0;
private currentTimeMs: number = 0;
- private audioRecorder: media.AudioRecorder = undefined;
- private timeUpdateListener: (currentTimeMs: number) => void = undefined;
- private stateUpdateListener: (RecordState) => void = undefined;
+ private audioRecorder?: media.AVRecorder;
+ private timeUpdateListener?: Callback;
+ private stateUpdateListener?: Callback;
/**
* Notification time update
@@ -71,9 +66,9 @@ export class RecordController {
*
* @param listener
*/
- public setTimeUpdateListener(listener: (currentTimeMs: number) => void) {
- LogUtil.info(`${TAG} setTimeUpdateListener.`);
- this.timeUpdateListener = listener;
+ public setTimeUpdateListener(tag: string, timeUpdateListener: Callback): void {
+ LogUtil.info(`${TAG} setTimeUpdateListener`);
+ this.timeUpdateListener = timeUpdateListener;
}
/**
@@ -81,58 +76,53 @@ export class RecordController {
*
* @param listener
*/
- public setStateUpdateListener(listener: (RecordState) => void) {
- LogUtil.info(`${TAG} setStateUpdateListener.`);
- this.stateUpdateListener = listener;
+ public setStateUpdateListener(tag: string, setStateUpdateListener: Callback): void {
+ LogUtil.info(`${TAG} setStateUpdateListener`);
+ this.stateUpdateListener = setStateUpdateListener;
}
/**
* init AudioRecorder
*/
- initAudioRecorder() {
+ async initAudioRecorder() {
LogUtil.info(`${TAG} initAudioRecorder.`);
- let recording_hint
- let suspend_record_hint
- globalThis.abilityContext.resourceManager.getString($r('app.string.recording_hint').id).then((value) => {
- recording_hint = value
- })
- globalThis.abilityContext.resourceManager.getString($r('app.string.suspend_record_hint').id).then((value) => {
- suspend_record_hint = value
- })
- this.audioRecorder = media.createAudioRecorder();
- this.audioRecorder.on('prepare', () => {
- LogUtil.info(`${TAG} audioRecorder prepare success.`);
- this.audioRecorder.start();
- });
- this.audioRecorder.on('start', () => {
- LogUtil.info(`${TAG} audioRecorder start success.`);
- this.publishNotification(recording_hint)
- this.startTime();
- });
- this.audioRecorder.on('pause', () => {
- LogUtil.info(`${TAG} audioRecorder pause success`);
- this.publishNotification(suspend_record_hint)
- clearInterval(this.notifierId);
- this.notifierId = -1;
- this.beforePauseTime += new Date().getTime() - this.startTimestamp;
- this.state = RecordState.PAUSED;
- this.notifyStateChanges();
- });
- this.audioRecorder.on('resume', () => {
- LogUtil.info(`${TAG} audioRecorder resume success`);
- this.publishNotification(recording_hint)
- this.startTime();
+ if (!this.audioRecorder) {
+ this.audioRecorder = await media.createAVRecorder();
+ }
+ this.setAVRecorderCallback(this.audioRecorder);
+ }
+
+ private setAVRecorderCallback(avRecorder: media.AVRecorder): void {
+ if (!avRecorder) {
+ return;
+ }
+ avRecorder.on('error', async (err: BusinessError) => {
+
});
- this.audioRecorder.on('stop', () => {
- LogUtil.info(`${TAG} audioRecorder stop success`);
- this.logoutNotification()
- this.audioRecorder.release();
- clearInterval(this.notifierId);
- this.notifierId = -1;
- this.state = RecordState.IDLE;
- this.currentTimeMs = 0;
- this.notifyStateChanges();
- this.notifyTimeChanges();
+ avRecorder.on('stateChange', async (state: string, resaon: media.StateChangeReason) => {
+ this.state = state;
+ switch (state) {
+ case 'idle':
+ break;
+ case 'initialized':
+ break;
+ case 'started':
+ break;
+ case 'prepared':
+ break;
+ case 'paused':
+ break;
+ case 'completed':
+ break;
+ case 'stopped':
+ break;
+ case 'released':
+ break;
+ case 'released':
+ break;
+ default:
+ break
+ }
});
}
@@ -148,36 +138,30 @@ export class RecordController {
*
* @param pathName
*/
- startRecorder(pathName) {
- if (typeof (this.audioRecorder) != 'undefined') {
- audioConfig.uri = pathName;
+ startRecorder(tag: string, filefd: number, filePath: string, config: media.AVRecorderConfig,
+ recorderStateCallback: Callback, onErrorCallback?: Callback) {
+ if (this.audioRecorder) {
+ this.recorderDuration = 0;
+ this.currentFilePath = filePath;
+ this.config = config;
+ this.openedFileFd = filefd;
+ if (this.audioRecorder.state === 'idle') {
+ this.audioRecorder.prepare(config);
+ } else {
+ this.audioRecorder.reset();
+ }
LogUtil.info(`${TAG} audioRecorder prepare.`);
- this.audioRecorder.prepare(audioConfig);
+ ;
} else {
LogUtil.error(`${TAG} case failed, audioRecorder is null.`);
}
}
- /**
- * start Time
- */
- startTime() {
- this.state = RecordState.RUNNING;
- this.startTimestamp = new Date().getTime();
- LogUtil.info(`${TAG} audioRecorder show time update start`);
- this.notifierId = setInterval(() => {
- let timestamp = new Date().getTime();
- this.currentTimeMs = this.beforePauseTime + timestamp - this.startTimestamp;
- this.notifyTimeChanges();
- }, NOTIFY_INTERVAL_MS);
- this.notifyStateChanges();
- }
-
/**
* Recorder pause
*/
pause() {
- if (typeof (this.audioRecorder) != `undefined`) {
+ if (this.audioRecorder) {
LogUtil.info(`${TAG} audioRecorder pause`);
this.audioRecorder.pause();
}
@@ -187,7 +171,7 @@ export class RecordController {
* Recorder resume
*/
resume() {
- if (typeof (this.audioRecorder) != `undefined`) {
+ if (this.audioRecorder) {
LogUtil.info(`${TAG} audioRecorder resume`);
this.audioRecorder.resume();
}
@@ -196,38 +180,10 @@ export class RecordController {
/**
* Recorder stop
*/
- stop(callback?) {
- if (typeof (this.audioRecorder) != `undefined`) {
+ stop() {
+ if (this.audioRecorder) {
LogUtil.info(`${TAG} audioRecorder stop`);
this.audioRecorder.stop();
- if (callback) {
- callback();
- }
}
}
-
- /**
- * publish Notification
- */
- publishNotification(text) {
- var notificationRequest = {
- id: NOTIFY_ID,
- content: {
- contentType: Notification.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT,
- normal: {
- title: text,
- text: ``,
- additionalText: ``
- }
- }
- }
- Notification.publish(notificationRequest)
- }
-
- /**
- * logout Notification
- */
- logoutNotification() {
- Notification.cancel(NOTIFY_ID)
- }
}
\ No newline at end of file
diff --git a/feature/recorder/src/main/ets/controller/StateController.ets b/feature/recorder/src/main/ets/controller/StateController.ets
index b8c1ea6f3e12f2cdfe000c6174faea17018a9e45..bf5bc9aaaa4630c8d59c43bfb9d42c7cf26c687d 100644
--- a/feature/recorder/src/main/ets/controller/StateController.ets
+++ b/feature/recorder/src/main/ets/controller/StateController.ets
@@ -14,6 +14,7 @@
*/
import { LogUtil } from '@ohos/common';
+import { BusinessError, Callback } from '@ohos.base'
const TAG = 'ControlState : ';
@@ -23,16 +24,17 @@ export enum ControlState {
}
export class StateController {
- private state: ControlState = ControlState.END;
- private stateUpdateListener: (RecordState) => void = undefined;
+ private state: number = 1;
+ private stateUpdateListener?: Callback;
/**
* Set the status update listener
*
* @param listener
*/
- public setStateUpdateListener(listener: (RecordState) => void) {
- this.stateUpdateListener = listener;
+ public setStateUpdateListener(tag: number, setStateUpdateListener: Callback): void {
+ LogUtil.info(`${TAG} setStateUpdateListener`);
+ this.stateUpdateListener = setStateUpdateListener;
}
/**
diff --git a/feature/recorder/src/main/ets/model/RecordData.ets b/feature/recorder/src/main/ets/model/RecordData.ets
index 60e96623cfaa5b9537d20eacafe8b215a76aee66..ab6a4855779936bcd3eb2a05b85087b93ac11e00 100644
--- a/feature/recorder/src/main/ets/model/RecordData.ets
+++ b/feature/recorder/src/main/ets/model/RecordData.ets
@@ -13,32 +13,31 @@
* limitations under the License.
*/
-import { default as MediaController } from '../controller/MediaController';
+import { MediaController } from '../controller/MediaController';
import mediaLibrary from '@ohos.multimedia.mediaLibrary';
export class RecordData {
- fileAsset: mediaLibrary.FileAsset;
- title: string;
- duration: number;
- date: number;
+ fileAsset: string = '';
+ title: string = '';
+ duration: number = 0;
+ date: number = 0;
- constructor(fileAsset: mediaLibrary.FileAsset) {
- this.fileAsset = fileAsset;
+ constructor(fileAsset: number, date: number, title: string) {
if (fileAsset) {
- if (fileAsset.duration > 0) {
- this.duration = fileAsset.duration;
+ if (fileAsset > 0) {
+ this.duration = fileAsset;
} else {
this.duration = 0;
}
- this.date = fileAsset.dateAdded;
- this.title = fileAsset.title;
+ if (date > 0) {
+ this.date = date;
+ } else {
+ this.date = 0;
+ }
+ this.title = title;
} else {
this.duration = 0;
this.title = '';
}
}
-
- async getDuration() {
- this.duration = Number(await MediaController.getFileDuration(this.fileAsset.title));
- }
}
\ No newline at end of file
diff --git a/hvigor/hvigor-config.json5 b/hvigor/hvigor-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..566ae69c011ea1dc3e50588a53fd9fbc1f6565e3
--- /dev/null
+++ b/hvigor/hvigor-config.json5
@@ -0,0 +1,11 @@
+{
+ "modelVersion": "5.0.2",
+ "dependencies": {
+ // "@ohos/hypium-plugin": "1.0.8-rc7",
+ // "fs-extra": "10.0.1",
+ // "execa": "5.1.1"
+ },
+ "debugging": {
+ "stacktrace": true
+ }
+}
\ No newline at end of file
diff --git a/oh-package-lock.json5 b/oh-package-lock.json5
new file mode 100644
index 0000000000000000000000000000000000000000..120748e7bcf733297ac3fa6cad639176c2cf6651
--- /dev/null
+++ b/oh-package-lock.json5
@@ -0,0 +1,20 @@
+{
+ "meta": {
+ "stableOrder": true
+ },
+ "lockfileVersion": 3,
+ "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
+ "specifiers": {
+ "@ohos/hypium@1.0.9": "@ohos/hypium@1.0.9"
+ },
+ "packages": {
+ "@ohos/hypium@1.0.9": {
+ "name": "@ohos/hypium",
+ "version": "1.0.9",
+ "integrity": "sha512-qW5HE293s8+YRwh+6reJjR1Q08iuhay2RdPJ/JJWOI9/mjHn/zMW4i/CUfhvqlAD2w+PXUfwAYoXItc4OQpo6A==",
+ "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.9.tgz",
+ "shasum": "c0b869cd51c7eb0764f90cb1a5b231d5512cef97",
+ "registryType": "ohpm"
+ }
+ }
+}
\ No newline at end of file
diff --git a/oh-package.json5 b/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..b6837c2a9728ec090995dfb41de67c4bbd09bcbe
--- /dev/null
+++ b/oh-package.json5
@@ -0,0 +1,20 @@
+{
+ "modelVersion": "5.0.2",
+ "license": "ISC",
+ "devDependencies": {},
+ "name": "ohosrecorder",
+ "ohos": {
+ "org": "huawei",
+ "directoryLevel": "project",
+ "buildTool": "hvigor"
+ },
+ "description": "example description",
+ "repository": {},
+ "version": "1.0.0",
+ "modelVersion": "5.0.2",
+ "dependencies": {
+ "@ohos/hypium": "1.0.9",
+ // "@ohos/hvigor-ohos-plugin":"1.1.6",
+ // "@ohos/hvigor":"1.1.6"
+ }
+}
\ No newline at end of file
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/CHANGELOG.md b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/CHANGELOG.md
new file mode 100644
index 0000000000000000000000000000000000000000..79c11d2bdeba38bc18f0f3bdf4723e4f1d77263b
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/CHANGELOG.md
@@ -0,0 +1,50 @@
+## 1.0.9
+
+- 测试hook方法支持断言与异常
+- 修复不能mock静态方法的问题
+
+## 1.0.6
+
+- 适配模块化编译
+- 适配IDE覆盖率数据输出
+
+## 1.0.5
+
+- 优化接口异常场景处理能力
+- 修复大规模压力测试下内存溢出问题
+- 修复测试脚本定义扩展原型方法与框架的兼容性问题
+- 异步promise状态判断断言与取反断言兼容
+
+## 1.0.4
+
+- 新增异步promise状态判断断言
+- 新增基础数据判断断言
+- 新增断言异常信息描述
+- 优化用例计时逻辑,采用相对时间计时
+- 修改用例执行过程,异步执行
+- 修复用例结果偶现的乱序问题
+
+## 1.0.3
+
+- 新增mock对象的能力,支持mock无参数函数
+- 新增测试套、测试用例随机执行功能
+- 解决测试套声明不规范,导致用例加载异常的问题
+- 修复命令行窗口输出乱序的问题
+
+## 1.0.2
+
+- 新增mock接口,判断当前mock方法状态、使用次数
+- 修复用例耗时统计问题
+- 修改断言功能,断言失败后,会抛出异常
+
+## 1.0.1
+- 新增mock基础能力
+- 修复部分断言失败后,消息提示异常问题
+
+## 1.0.0
+- 新增应用日志关键字查询接口,查询hilog日志中是否包含指定字符串
+- 支持用例筛选功能,用于指定测试用例的执行。可按用例名称、类型、规模、级别与测试套名称筛选
+- 支持新SDK下单元测试
+- 支持dry run 功能,通过命令行传参数,返回当前测试套用例名称全集
+- 新增框架接口声明文件,用于deveco联想
+- 修复用例状态统计问题
\ No newline at end of file
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/LICENSE b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..4947287f7b5ccb5d1e8b7b2d3aa5d89f322c160d
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
\ No newline at end of file
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/README.md b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..83ddccc702c7b280100436d0a428bae203eb7f4b
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/README.md
@@ -0,0 +1,219 @@
+
Hypium
+
A unit test framework for OpenHarmonyOS application
+
+## Hypium是什么?
+***
+- Hypium是OpenHarmony上的测试框架,提供测试用例编写、执行、结果显示能力,用于OpenHarmony系统应用接口以及应用界面测试。
+- Hypium结构化模型:hypium工程主要由List.test.js与TestCase.test.js组成。
+```
+rootProject // Hypium工程根目录
+├── moduleA
+│ ├── src
+│ ├── main // 被测试应用目录
+│ ├── ohosTest // 测试用例目录
+│ ├── js/ets
+│ └── test
+│ └── List.test.js // 测试用例加载脚本,ets目录下为.ets后缀
+│ └── TestCase.test.js // 测试用例脚本,ets目录下为.ets后缀
+└── moduleB
+ ...
+│ └── List.test.js // 测试用例加载脚本,ets目录下为.ets后缀
+│ └── TestCase.test.js // 测试用例脚本,ets目录下为.ets后缀
+```
+
+## 安装使用
+***
+- 在DevEco Studio内使用Hypium
+- 工程级package.json内配置:
+```json
+"dependencies": {
+ "@ohos/hypium": "1.0.9"
+}
+```
+注:
+hypium服务于OpenHarmonyOS应用对外接口测试、系统对外接口测试(SDK中接口),完成HAP自动化测试。详细指导:
+[Deveco Studio](https://developer.harmonyos.com/cn/develop/deveco-studio)
+
+#### 通用语法
+
+- 测试用例采用业内通用语法,describe代表一个测试套, it代表一条用例。
+
+| No. | API | 功能说明 |
+| --- | ---------- | ---------------------------------------------------------------------------------------------------------------------- |
+| 1 | describe | 定义一个测试套,支持两个参数:测试套名称和测试套函数 |
+| 2 | beforeAll | 在测试套内定义一个预置条件,在所有测试用例开始前执行且仅执行一次,支持一个参数:预置动作函数 |
+| 3 | beforeEach | 在测试套内定义一个单元预置条件,在每条测试用例开始前执行,执行次数与it定义的测试用例数一致,支持一个参数:预置动作函数 |
+| 4 | afterEach | 在测试套内定义一个单元清理条件,在每条测试用例结束后执行,执行次数与it定义的测试用例数一致,支持一个参数:清理动作函数 |
+| 5 | afterAll | 在测试套内定义一个清理条件,在所有测试用例结束后执行且仅执行一次,支持一个参数:清理动作函数 |
+| 6 | it | 定义一条测试用例,支持三个参数:用例名称,过滤参数和用例函数 |
+| 7 | expect | 支持bool类型判断等多种断言方法 |
+
+#### 断言库
+
+- 示例代码:
+
+```javascript
+ expect(${actualvalue}).assertX(${expectvalue})
+```
+
+- 断言功能列表:
+
+| No. | API | 功能说明 |
+| :--- | :------------------------------- | ---------------------------------------------------------------------------------------------- |
+| 1 | assertClose | 检验actualvalue和expectvalue(0)的接近程度是否是expectValue(1) |
+| 2 | assertContain | 检验actualvalue中是否包含expectvalue |
+| 3 | assertDeepEquals | @since1.0.4 检验actualvalue和expectvalue(0)是否是同一个对象 |
+| 4 | assertEqual | 检验actualvalue是否等于expectvalue[0] |
+| 5 | assertFail | 抛出一个错误 |
+| 6 | assertFalse | 检验actualvalue是否是false |
+| 7 | assertTrue | 检验actualvalue是否是true |
+| 8 | assertInstanceOf | 检验actualvalue是否是expectvalue类型 |
+| 9 | assertLarger | 检验actualvalue是否大于expectvalue |
+| 10 | assertLess | 检验actualvalue是否小于expectvalue |
+| 11 | assertNaN | @since1.0.4 检验actualvalue是否是NaN |
+| 12 | assertNegUnlimited | @since1.0.4 检验actualvalue是否等于Number.NEGATIVE_INFINITY |
+| 13 | assertNull | 检验actualvalue是否是null |
+| 14 | assertPosUnlimited | @since1.0.4 检验actualvalue是否等于Number.POSITIVE_INFINITY |
+| 15 | assertPromiseIsPending | @since1.0.4 检验actualvalue是否处于Pending状态【actualvalue为promse对象】 |
+| 16 | assertPromiseIsRejected | @since1.0.4 检验actualvalue是否处于Rejected状态【同15】 |
+| 17 | assertPromiseIsRejectedWith | @since1.0.4 检验actualvalue是否处于Rejected状态,并且比较执行的结果值【同15】 |
+| 18 | assertPromiseIsRejectedWithError | @since1.0.4 检验actualvalue是否处于Rejected状态并有异常,同时比较异常的类型和message值【同15】 |
+| 19 | assertPromiseIsResolved | @since1.0.4 检验actualvalue是否处于Resolved状态【同15】 |
+| 20 | assertPromiseIsResolvedWith | @since1.0.4 检验actualvalue是否处于Resolved状态,并且比较执行的结果值【同15】 |
+| 21 | assertThrowError | 检验actualvalue抛出Error内容是否是expectValue |
+| 22 | assertUndefined | 检验actualvalue是否是undefined |
+| 23 | not | @since1.0.4 断言结果取反 |
+
+
+ 示例代码:
+
+```javascript
+ import { describe, it, expect } from '@ohos/hypium';
+
+ export default async function assertCloseTest() {
+ describe('assertClose', function () {
+ it('assertClose_success', 0, function () {
+ let a = 100;
+ let b = 0.1;
+ expect(a).assertClose(99, b);
+ })
+ })
+ }
+```
+
+#### 公共系统能力
+
+| No. | API | 功能描述 |
+| ---- | ------------------------------------------------------- | ------------------------------------------------------------ |
+| 1 | existKeyword(keyword: string, timeout: number): boolean | @since1.0.3 hilog日志中查找指定字段是否存在,keyword是待查找关键字,timeout为设置的查找时间 |
+| 2 | actionStart(tag: string): void | @since1.0.3 cmd窗口输出开始tag |
+| 3 | actionEnd(tag: string): void | @since1.0.3 cmd窗口输出结束tag |
+
+ 示例代码:
+
+```javascript
+import { describe, it, expect, SysTestKit} from '@ohos/hypium';
+
+export default function existKeywordTest() {
+ describe('existKeywordTest', function () {
+ it('existKeyword',DEFAULT, async function () {
+ console.info("HelloTest");
+ let isExist = await SysTestKit.existKeyword('HelloTest');
+ console.info('isExist ------>' + isExist);
+ })
+ })
+}
+```
+```javascript
+import { describe, it, expect, SysTestKit} from '@ohos/hypium';
+
+export default function actionTest() {
+ describe('actionTest', function () {
+ it('existKeyword',DEFAULT, async function () {
+ let tag = '[MyTest]';
+ SysTestKit.actionStart(tag);
+ //do something
+ SysTestKit.actionEnd(tag);
+ })
+ })
+}
+```
+
+#### 专项能力
+
+- 测试用例属性筛选能力:hypium支持根据用例属性筛选执行指定测试用例,使用方式是先在测试用例上标记用例属性后,再在测试应用的启动shell命令后新增" -s ${Key} ${Value}"。
+
+| Key | 含义说明 | Value取值范围 |
+| -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| level | 用例级别 | "0","1","2","3","4", 例如:-s level 1 |
+| size | 用例粒度 | "small","medium","large", 例如:-s size small |
+| testType | 用例测试类型 | "function","performance","power","reliability","security","global","compatibility","user","standard","safety","resilience", 例如:-s testType function |
+
+ 示例代码
+
+```javascript
+import { describe, it, expect, TestType, Size, Level } from '@ohos/hypium';
+
+export default function attributeTest() {
+ describe('attributeTest', function () {
+ it("testAttributeIt", TestType.FUNCTION | Size.SMALLTEST | Level.LEVEL0, function () {
+ console.info('Hello Test');
+ })
+ })
+}
+```
+
+ 示例命令
+```shell
+XX -s level 1 -s size small -s testType function
+```
+该命令的作用是:筛选测试应用中同时满足a)用例级别是1 b)用例粒度是small c)用例测试类型是function 三个条件的用例执行。
+
+- 测试套/测试用例名称筛选能力(测试套与用例名称用“#”号连接,多个用“,”英文逗号分隔)
+
+| Key | 含义说明 | Value取值范围 |
+| -------- | ----------------------- | -------------------------------------------------------------------------------------------- |
+| class | 指定要执行的测试套&用例 | ${describeName}#${itName},${describeName} , 例如:-s class attributeTest#testAttributeIt |
+| notClass | 指定不执行的测试套&用例 | ${describeName}#${itName},${describeName} , 例如:-s notClass attributeTest#testAttributeIt |
+
+ 示例命令
+```shell
+XX -s class attributeTest#testAttributeIt,abilityTest#testAbilityIt
+```
+该命令的作用是:筛选测试应用中attributeTest测试套下的testAttributeIt测试用例,abilityTest测试套下的testAbilityIt测试用例,只执行这两条用例。
+
+- 其他能力
+
+| 能力项 | Key | 含义说明 | Value取值范围 |
+| ------------ | ------- | ---------------------------- | ---------------------------------------------- |
+| 随机执行能力 | random | 测试套&测试用例随机执行 | true, 不传参默认为false, 例如:-s random true |
+| 空跑能力 | dryRun | 显示要执行的测试用例信息全集 | true , 不传参默认为false,例如:-s dryRun true |
+| 异步超时能力 | timeout | 异步用例执行的超时时间 | 正整数 , 单位ms,例如:-s timeout 5000 |
+
+##### 约束限制
+随机执行能力和空跑能力从npm包1.0.3版本开始支持
+
+#### Mock能力
+
+##### 约束限制
+
+单元测试框架Mock能力从npm包[1.0.1版本](https://repo.harmonyos.com/#/cn/application/atomService/@ohos%2Fhypium/v/1.0.1)开始支持
+
+## 约束
+
+***
+ 本模块首批接口从OpenHarmony SDK API version 8开始支持。
+
+## Hypium开放能力隐私声明
+
+- 我们如何收集和使用您的个人信息
+ 您在使用集成了Hypium开放能力的测试应用时,Hypium不会处理您的个人信息。
+- SDK处理的个人信息
+ 不涉及。
+- SDK集成第三方服务声明
+ 不涉及。
+- SDK数据安全保护
+ 不涉及。
+- SDK版本更新声明
+ 为了向您提供最新的服务,我们会不时更新Hypium版本。我们强烈建议开发者集成使用最新版本的Hypium。
+
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/index.d.ts b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/index.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b0b4394a3284c07e873e84c9144cd31889e1863d
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/index.d.ts
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export const DEFAULT = 0B0000
+
+export const when: when;
+
+export enum TestType {
+ FUNCTION = 0B1,
+ PERFORMANCE = 0B1 << 1,
+ POWER = 0B1 << 2,
+ RELIABILITY = 0B1 << 3,
+ SECURITY = 0B1 << 4,
+ GLOBAL = 0B1 << 5,
+ COMPATIBILITY = 0B1 << 6,
+ USER = 0B1 << 7,
+ STANDARD = 0B1 << 8,
+ SAFETY = 0B1 << 9,
+ RESILIENCE = 0B1 << 10
+}
+
+export enum Size {
+ SMALLTEST = 0B1 << 16,
+ MEDIUMTEST = 0B1 << 17,
+ LARGETEST = 0B1 << 18
+}
+
+export enum Level {
+ LEVEL0 = 0B1 << 24,
+ LEVEL1 = 0B1 << 25,
+ LEVEL2 = 0B1 << 26,
+ LEVEL3 = 0B1 << 27,
+ LEVEL4 = 0B1 << 28
+}
+
+export function describe(testSuiteName: string, callback: Function): void
+
+export function beforeEach(callback: Function): void
+
+export function afterEach(callback: Function): void
+
+export function beforeAll(callback: Function): void
+
+export function afterAll(callback: Function): void
+
+export function it(testCaseName: string, attribute: (TestType | Size | Level), callback: Function)
+
+export interface Assert {
+ assertClose(expectValue: number, precision: number): void
+ assertContain(expectValue: any): void
+ assertEqual(expectValue: any): void
+ assertFail(): void
+ assertFalse(): void
+ assertTrue(): void
+ assertInstanceOf(expectValue: string): void
+ assertLarger(expectValue: number): void
+ assertLess(expectValue: number): void
+ assertNull(): void
+ assertThrowError(expectValue: string): void
+ assertUndefined(): void
+ assertLargerOrEqual(expectValue: number):void
+ assertLessOrEqual(expectValue: number):void
+ assertNaN():void
+ assertNegUnlimited(): void
+ assertPosUnlimited(): void
+ not(): Assert;
+ assertDeepEquals(expectValue: any):void
+ assertPromiseIsPending(): void
+ assertPromiseIsRejected(): void
+ assertPromiseIsRejectedWith(expectValue?: any): void
+ assertPromiseIsRejectedWithError(...expectValue): void
+ assertPromiseIsResolved(): void
+ assertPromiseIsResolvedWith(expectValue?: any): void
+}
+
+export function expect(actualValue?: any): Assert
+
+export class ArgumentMatchers {
+ static any;
+ static anyString;
+ static anyBoolean;
+ static anyNumber;
+ static anyObj;
+ static anyFunction;
+ static matchRegexs(Regex: RegExp): void
+}
+
+declare interface when {
+ afterReturn(value: any): any
+ afterReturnNothing(): undefined
+ afterAction(action: any): any
+ afterThrow(e_msg: string): string
+ (argMatchers?: any): when;
+}
+
+export interface VerificationMode {
+ times(count: Number): void
+ never(): void
+ once(): void
+ atLeast(count: Number): void
+ atMost(count: Number): void
+}
+
+export class MockKit {
+ constructor()
+ mockFunc(obj: Object, func: Function): Function
+ mockObject(obj: Object): Object
+ verify(methodName: String, argsArray: Array): VerificationMode
+ ignoreMock(obj: Object, func: Function): void
+ clear(obj: Object): void
+ clearAll(): void
+}
+
+export class SysTestKit {
+ static actionStart(tag: string): void
+ static actionEnd(tag: string): void
+ static existKeyword(keyword: string, timeout?: number): boolean
+}
+
+export class Hypium {
+ static setData(data: {[key: string]: any}): void
+ static setTimeConfig(systemTime: any)
+ static hypiumTest(abilityDelegator: any, abilityDelegatorArguments: any, testsuite: Function): void
+}
\ No newline at end of file
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/index.ets b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..355d006f5cd3e7f5e9d1a83374ad1dc0b588d1a0
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/index.ets
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Core from './src/main/core';
+import {ConfigService} from './src/main/module/config/configService'
+import {DEFAULT, TestType, Size, Level, TAG} from './src/main/Constant';
+import DataDriver from './src/main/module/config/DataDriver';
+import ExpectExtend from './src/main/module/assert/ExpectExtend';
+import OhReport from './src/main/module/report/OhReport';
+import SysTestKit from './src/main/module/kit/SysTestKit';
+import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from './src/main/interface';
+import {MockKit, when} from './src/main/module/mock/MockKit';
+import ArgumentMatchers from './src/main/module/mock/ArgumentMatchers';
+
+interface AbilityDelegatorArgs {
+ bundleName: string;
+ parameters: Object;
+ testCaseNames: string;
+ testRunnerClassName: string;
+}
+
+class Hypium {
+ static setData(data:Object) {
+ const core = Core.getInstance();
+ const dataDriver = new DataDriver({data});
+ core.addService('dataDriver', dataDriver);
+ }
+
+ static setTimeConfig(systemTime:Object) {
+ SysTestKit.systemTime = systemTime;
+ }
+
+ static hypiumTest(abilityDelegator:Object, abilityDelegatorArguments:AbilityDelegatorArgs, testsuite:Function) {
+ const core = Core.getInstance();
+ const expectExtend = new ExpectExtend({
+ id: 'extend'
+ });
+ core.addService('expect', expectExtend);
+ const ohReport = new OhReport({
+ delegator: abilityDelegator,
+ abilityDelegatorArguments: abilityDelegatorArguments
+ });
+ SysTestKit.delegator = abilityDelegator;
+ core.addService('report', ohReport);
+ core.init();
+ core.subscribeEvent('spec', ohReport);
+ core.subscribeEvent('suite', ohReport);
+ core.subscribeEvent('task', ohReport);
+ const configService:ConfigService = core.getDefaultService('config');
+ let testParameters:Object = null;
+ if (abilityDelegatorArguments !== null) {
+ testParameters = configService.translateParams(abilityDelegatorArguments.parameters);
+ }
+ console.info(`${TAG}parameters:${JSON.stringify(testParameters)}`);
+ configService.setConfig(testParameters);
+
+ testsuite();
+ core.execute(abilityDelegator);
+ }
+}
+
+export {
+ Hypium,
+ Core,
+ DEFAULT,
+ TestType,
+ Size,
+ Level,
+ DataDriver,
+ ExpectExtend,
+ OhReport,
+ SysTestKit,
+ describe, beforeAll, beforeEach, afterEach, afterAll, it, expect,
+ MockKit, when,
+ ArgumentMatchers
+};
\ No newline at end of file
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/index.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..affc83beb4c94a3aa9440bd69069ebced10c9109
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/index.js
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Core from './src/main/core';
+import {DEFAULT, TestType, Size, Level, TAG} from './src/main/Constant';
+import DataDriver from './src/main/module/config/DataDriver';
+import ExpectExtend from './src/main/module/assert/ExpectExtend';
+import OhReport from './src/main/module/report/OhReport';
+import SysTestKit from './src/main/module/kit/SysTestKit';
+import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from './src/main/interface';
+import {MockKit, when} from './src/main/module/mock/MockKit';
+import ArgumentMatchers from './src/main/module/mock/ArgumentMatchers';
+
+class Hypium {
+ static setData(data) {
+ const core = Core.getInstance();
+ const dataDriver = new DataDriver({data});
+ core.addService('dataDriver', dataDriver);
+ }
+
+ static setTimeConfig(systemTime) {
+ SysTestKit.systemTime = systemTime;
+ }
+
+ static hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) {
+ const core = Core.getInstance();
+ const expectExtend = new ExpectExtend({
+ 'id': 'extend'
+ });
+ core.addService('expect', expectExtend);
+ const ohReport = new OhReport({
+ 'delegator': abilityDelegator,
+ 'abilityDelegatorArguments': abilityDelegatorArguments
+ });
+ SysTestKit.delegator = abilityDelegator;
+ core.addService('report', ohReport);
+ core.init();
+ core.subscribeEvent('spec', ohReport);
+ core.subscribeEvent('suite', ohReport);
+ core.subscribeEvent('task', ohReport);
+ const configService = core.getDefaultService('config');
+
+ let testParameters = {};
+ if (abilityDelegatorArguments !== null) {
+ testParameters = configService.translateParams(abilityDelegatorArguments.parameters);
+ }
+ console.info(`${TAG}parameters:${JSON.stringify(testParameters)}`);
+ configService.setConfig(testParameters);
+
+ testsuite();
+ core.execute(abilityDelegator);
+ }
+}
+
+export {
+ Hypium,
+ Core,
+ DEFAULT,
+ TestType,
+ Size,
+ Level,
+ DataDriver,
+ ExpectExtend,
+ OhReport,
+ SysTestKit,
+ describe, beforeAll, beforeEach, afterEach, afterAll, it, expect,
+ MockKit, when,
+ ArgumentMatchers
+};
\ No newline at end of file
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/oh-package.json5 b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..586263cbcdd5006e495ee4176cdec5b96812dcae
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/oh-package.json5
@@ -0,0 +1,11 @@
+{
+ "name": "@ohos/hypium",
+ "version": "1.0.9",
+ "description": "A unit test framework for OpenHarmony application",
+ "main": "index.js",
+ "keywords": [],
+ "author": "huawei",
+ "license": "Apache-2.0",
+ "dependencies": {
+ }
+}
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/Constant.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/Constant.js
new file mode 100644
index 0000000000000000000000000000000000000000..13f68499c8688027eb2dc49c6dc4028610ab480c
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/Constant.js
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * define the testcase type : TestType, Size , Level
+ */
+export const TAG = '[Hypium]';
+
+export const DEFAULT = 0B0000;
+
+export class TestType {
+ static FUNCTION = 0B1;
+ static PERFORMANCE = 0B1 << 1;
+ static POWER = 0B1 << 2;
+ static RELIABILITY = 0B1 << 3;
+ static SECURITY = 0B1 << 4;
+ static GLOBAL = 0B1 << 5;
+ static COMPATIBILITY = 0B1 << 6;
+ static USER = 0B1 << 7;
+ static STANDARD = 0B1 << 8;
+ static SAFETY = 0B1 << 9;
+ static RESILIENCE = 0B1 << 10;
+}
+
+export class Size {
+ static SMALLTEST = 0B1 << 16;
+ static MEDIUMTEST = 0B1 << 17;
+ static LARGETEST = 0B1 << 18;
+}
+
+export class Level {
+ static LEVEL0 = 0B1 << 24;
+ static LEVEL1 = 0B1 << 25;
+ static LEVEL2 = 0B1 << 26;
+ static LEVEL3 = 0B1 << 27;
+ static LEVEL4 = 0B1 << 28;
+}
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/core.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/core.js
new file mode 100644
index 0000000000000000000000000000000000000000..cfcb5f17287208f5e6869b4248faf6c9093002d9
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/core.js
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {SuiteService, SpecService, ExpectService, ReportService} from './service';
+import {ConfigService} from './module/config/configService';
+import {SpecEvent, TaskEvent, SuiteEvent} from './event';
+
+/**
+ * core service for execute testcase.
+ */
+class Core {
+ static getInstance() {
+ if (!this.instance) {
+ this.instance = new Core();
+ }
+ return this.instance;
+ }
+
+ constructor() {
+ this.instance = null;
+ this.services = {
+ suite: {},
+ spec: {},
+ config: {},
+ expect: {},
+ log: {},
+ report: {}
+
+ };
+ this.events = {
+ suite: {},
+ spec: {},
+ task: {}
+ };
+ }
+
+ addService(name, service) {
+ let serviceObj = {};
+ if (!this.services[name]) {
+ this.services[name] = serviceObj;
+ } else {
+ serviceObj = this.services[name];
+ }
+ serviceObj[service.id] = service;
+ }
+
+ getDefaultService(name) {
+ return this.services[name].default;
+ }
+
+ getServices(name) {
+ return this.services[name];
+ }
+
+ registerEvent(serviceName, event) {
+ let eventObj = {};
+ if (!this.events[serviceName]) {
+ this.events[serviceName] = eventObj;
+ } else {
+ eventObj = this.events[serviceName];
+ }
+ eventObj[event.id] = event;
+ }
+
+ unRegisterEvent(serviceName, eventID) {
+ const eventObj = this.events[serviceName];
+ if (eventObj) {
+ delete eventObj[eventID];
+ }
+ }
+
+ subscribeEvent(serviceName, serviceObj) {
+ const eventObj = this.events[serviceName];
+ if (eventObj) {
+ for (const attr in eventObj) {
+ eventObj[attr]['subscribeEvent'](serviceObj);
+ }
+ }
+ }
+
+ async fireEvents(serviceName, eventName) {
+ const eventObj = this.events[serviceName];
+ if (!eventObj) {
+ return;
+ }
+ for (const attr in eventObj) {
+ await eventObj[attr][eventName]();
+ }
+ }
+
+ addToGlobal(apis) {
+ if (typeof globalThis !== 'undefined') {
+ for (let api in apis) {
+ globalThis[api] = apis[api];
+ }
+ }
+ for (const api in apis) {
+ this[api] = apis[api];
+ }
+ }
+
+ init() {
+ this.addService('suite', new SuiteService({id: 'default'}));
+ this.addService('spec', new SpecService({id: 'default'}));
+ this.addService('expect', new ExpectService({id: 'default'}));
+ this.addService('report', new ReportService({id: 'default'}));
+ this.addService('config', new ConfigService({id: 'default'}));
+ this.registerEvent('task', new TaskEvent({id: 'default', coreContext: this}));
+ this.registerEvent('suite', new SuiteEvent({id: 'default', coreContext: this}));
+ this.registerEvent('spec', new SpecEvent({id: 'default', coreContext: this}));
+ this.subscribeEvent('spec', this.getDefaultService('report'));
+ this.subscribeEvent('suite', this.getDefaultService('report'));
+ this.subscribeEvent('task', this.getDefaultService('report'));
+ const context = this;
+ for (const key in this.services) {
+ const serviceObj = this.services[key];
+ for (const serviceID in serviceObj) {
+ const service = serviceObj[serviceID];
+ service.init(context);
+
+ if (typeof service.apis !== 'function') {
+ continue;
+ }
+ const apis = service.apis();
+ if (apis) {
+ this.addToGlobal(apis);
+ }
+ }
+ }
+ }
+
+ execute(abilityDelegator) {
+ const suiteService = this.getDefaultService('suite');
+ const configService = this.getDefaultService('config');
+ if (configService['dryRun'] === 'true') {
+ (async function () {
+ await suiteService.dryRun(abilityDelegator);
+ })();
+ return;
+ }
+ setTimeout(() => {
+ suiteService.execute();
+ }, 10);
+ }
+}
+
+export default Core;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/event.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/event.js
new file mode 100644
index 0000000000000000000000000000000000000000..1333a1c483f9a2aa1c45e133b1d3cbbc7cdb8346
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/event.js
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class SpecEvent {
+ constructor(attr) {
+ this.id = attr.id;
+ this.coreContext = attr.context;
+ this.eventMonitors = [];
+ }
+
+ subscribeEvent(service) {
+ this.eventMonitors.push(service);
+ }
+
+ async specStart() {
+ for (const monitor of this.eventMonitors) {
+ await monitor['specStart']();
+ }
+ }
+
+ async specDone() {
+ for (const monitor of this.eventMonitors) {
+ await monitor['specDone']();
+ }
+ }
+}
+
+class SuiteEvent {
+ constructor(attr) {
+ this.id = attr.id;
+ this.suiteContext = attr.coreContext;
+ this.eventMonitors = [];
+ }
+
+ subscribeEvent(service) {
+ this.eventMonitors.push(service);
+ }
+
+ async suiteStart() {
+ for (const monitor of this.eventMonitors) {
+ await monitor['suiteStart']();
+ }
+ }
+
+ async suiteDone() {
+ for (const monitor of this.eventMonitors) {
+ await monitor['suiteDone']();
+ }
+ }
+}
+
+class TaskEvent {
+ constructor(attr) {
+ this.id = attr.id;
+ this.coreContext = attr.coreContext;
+ this.eventMonitors = [];
+ }
+
+ subscribeEvent(service) {
+ this.eventMonitors.push(service);
+ }
+
+ async taskStart() {
+ for (const monitor of this.eventMonitors) {
+ await monitor['taskStart']();
+ }
+ }
+
+ async taskDone() {
+ for (const monitor of this.eventMonitors) {
+ await monitor['taskDone']();
+ }
+ }
+
+ incorrectFormat() {
+ for (const monitor of this.eventMonitors) {
+ monitor['incorrectFormat']();
+ }
+ }
+}
+
+export {SpecEvent, TaskEvent, SuiteEvent};
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/interface.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/interface.js
new file mode 100644
index 0000000000000000000000000000000000000000..40398c849d55cd76ab64fcba26899b547e2a3c97
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/interface.js
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Core from './core';
+
+const core = Core.getInstance();
+
+const describe = function (desc, func) {
+ return Reflect.has(core, 'describe') ? core.describe(desc, func) : (desc, func) => { };
+};
+const it = function (desc, filter, func) {
+ return Reflect.has(core, 'it') ? core.it(desc, filter, func) : (desc, filter, func) => { };
+};
+const beforeEach = function (func) {
+ return Reflect.has(core, 'beforeEach') ? core.beforeEach(func) : (func) => { };
+};
+const afterEach = function (func) {
+ return Reflect.has(core, 'afterEach') ? core.afterEach(func) : (func) => { };
+};
+const beforeAll = function (func) {
+ return Reflect.has(core, 'beforeAll') ? core.beforeAll(func) : (func) => { };
+};
+const afterAll = function (func) {
+ return Reflect.has(core, 'afterAll') ? core.afterAll(func) : (func) => { };
+};
+const expect = function (actualValue) {
+ return Reflect.has(core, 'expect') ? core.expect(actualValue) : (actualValue) => { };
+};
+
+export {
+ describe, it, beforeAll, beforeEach, afterEach, afterAll, expect
+};
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/ExpectExtend.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/ExpectExtend.js
new file mode 100644
index 0000000000000000000000000000000000000000..d10d15e6f9955c6d04610101f8766c951ee1a35d
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/ExpectExtend.js
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import assertNull from './assertNull';
+import assertClose from './assertClose';
+import assertContain from './assertContain';
+import assertLess from './assertLess';
+import assertLarger from './assertLarger';
+import assertFail from './assertFail';
+import assertUndefined from './assertUndefined';
+import assertFalse from './assertFalse';
+import assertInstanceOf from './assertInstanceOf';
+import assertThrowError from './assertThrowError';
+import assertLargerOrEqual from './assertLargerOrEqual'
+import assertLessOrEqual from './assertLessOrEqual'
+import assertNaN from './assertNaN'
+import assertNegUnlimited from './assertNegUnlimited'
+import assertPosUnlimited from './assertPosUnlimited'
+import assertDeepEquals from './deepEquals/assertDeepEquals'
+import assertPromiseIsPending from './assertPromiseIsPending';
+import assertPromiseIsRejected from './assertPromiseIsRejected';
+import assertPromiseIsRejectedWith from './assertPromiseIsRejectedWith';
+import assertPromiseIsRejectedWithError from './assertPromiseIsRejectedWithError';
+import assertPromiseIsResolved from './assertPromiseIsResolved';
+import assertPromiseIsResolvedWith from './assertPromiseIsResolvedWith';
+class ExpectExtend {
+ constructor(attr) {
+ this.id = attr.id;
+ this.matchers = {};
+ }
+
+ extendsMatchers() {
+ this.matchers.assertNull = assertNull;
+ this.matchers.assertClose = assertClose;
+ this.matchers.assertContain = assertContain;
+ this.matchers.assertLess = assertLess;
+ this.matchers.assertLarger = assertLarger;
+ this.matchers.assertFail = assertFail;
+ this.matchers.assertUndefined = assertUndefined;
+ this.matchers.assertFalse = assertFalse;
+ this.matchers.assertInstanceOf = assertInstanceOf;
+ this.matchers.assertThrowError = assertThrowError;
+ this.matchers.assertLargerOrEqual = assertLargerOrEqual;
+ this.matchers.assertLessOrEqual = assertLessOrEqual;
+ this.matchers.assertNaN = assertNaN;
+ this.matchers.assertNegUnlimited = assertNegUnlimited;
+ this.matchers.assertPosUnlimited = assertPosUnlimited;
+ this.matchers.assertDeepEquals = assertDeepEquals;
+ this.matchers.assertPromiseIsPending = assertPromiseIsPending;
+ this.matchers.assertPromiseIsRejected = assertPromiseIsRejected;
+ this.matchers.assertPromiseIsRejectedWith = assertPromiseIsRejectedWith;
+ this.matchers.assertPromiseIsRejectedWithError = assertPromiseIsRejectedWithError;
+ this.matchers.assertPromiseIsResolved = assertPromiseIsResolved;
+ this.matchers.assertPromiseIsResolvedWith = assertPromiseIsResolvedWith;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ this.extendsMatchers();
+ const expectService = this.coreContext.getDefaultService('expect');
+ expectService.addMatchers(this.matchers);
+ }
+
+ apis() {
+ return {
+ 'expect': function (actualValue) {
+ return this.coreContext.getDefaultService('expect').expect(actualValue);
+ }
+ };
+ }
+}
+
+export default ExpectExtend;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertClose.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertClose.js
new file mode 100644
index 0000000000000000000000000000000000000000..63635bea5bf1298776de565260e0e0babae56857
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertClose.js
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertClose(actualValue, expected) {
+ console.log('expected:' + expected[0] + ',precision:' + expected[1]);
+ if (actualValue === null && expected[0] === null) {
+ throw new Error('actualValue and expected can not be both null!!!');
+ }
+ let result;
+ let diff = Math.abs(expected[0] - actualValue);
+ let actualAbs = Math.abs(actualValue);
+ if ((actualAbs - 0) === 0) {
+ if ((diff - 0) === 0) {
+ result = true;
+ } else {
+ result = false;
+ }
+ } else if (diff / actualAbs < expected[1]) {
+ result = true;
+ } else {
+ result = false;
+ }
+ return {
+ pass: result,
+ message: '|' + actualValue + ' - ' + expected[0] + '|/' + actualValue + ' is not less than ' + expected[1]
+ };
+}
+
+export default assertClose;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertContain.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertContain.js
new file mode 100644
index 0000000000000000000000000000000000000000..7fba0d9755503e5e926f6c1a4e425e0d1cf47570
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertContain.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertContain(actualValue, expect) {
+ let result = false;
+ if (Object.prototype.toString.call(actualValue).indexOf('Array')) {
+ for (let i in actualValue) {
+ if (actualValue[i] == expect[0]) {
+ result = true;
+ }
+ }
+ }
+ let type = Object.prototype.toString.call(actualValue);
+ if (type === '[object String]') {
+ result = actualValue.indexOf(expect[0]) >= 0;
+ }
+ return {
+ pass: result,
+ message: 'expect false, ' + actualValue + ' do not have ' + expect[0]
+ };
+}
+
+export default assertContain;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertFail.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertFail.js
new file mode 100644
index 0000000000000000000000000000000000000000..8ab4ac5caef712c75c4eac49dfbbb91d33669d9a
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertFail.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertFail() {
+ return {
+ pass: false,
+ message: 'fail '
+ };
+}
+
+export default assertFail;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertFalse.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertFalse.js
new file mode 100644
index 0000000000000000000000000000000000000000..c5008e94f4b2ce13ed35b604811793c76b542347
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertFalse.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertFalse(actualValue) {
+ return {
+ pass: (actualValue) === false,
+ message: 'expect false, actualValue is ' + actualValue
+ };
+}
+
+export default assertFalse;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertInstanceOf.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertInstanceOf.js
new file mode 100644
index 0000000000000000000000000000000000000000..1e11b93f7251c67f5455c5007cd7be268aa53b32
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertInstanceOf.js
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertInstanceOf(actualValue, expected) {
+ if (Object.prototype.toString.call(actualValue) == '[object ' + expected[0] + ']') {
+ return {
+ pass: true
+ };
+ } else {
+ return {
+ pass: false,
+ message: actualValue + ' is ' + Object.prototype.toString.call(actualValue) + 'not ' + expected[0]
+ };
+ }
+}
+
+export default assertInstanceOf;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertLarger.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertLarger.js
new file mode 100644
index 0000000000000000000000000000000000000000..a74f4a8cedaf3add9c2dc2d3799081a83198732f
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertLarger.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertLarger(actualValue, expected) {
+ return {
+ pass: (actualValue) > expected[0],
+ message: (actualValue) + ' is not larger than ' + expected[0]
+ };
+}
+
+export default assertLarger;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertLargerOrEqual.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertLargerOrEqual.js
new file mode 100644
index 0000000000000000000000000000000000000000..e847e6c217364b7f69c173c66fb98d10efc45ef1
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertLargerOrEqual.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertLargerOrEqual(actualValue, expected) {
+ return {
+ pass: (actualValue) >= expected[0],
+ message: (actualValue) + ' is not larger than ' + expected[0]
+ };
+}
+
+export default assertLargerOrEqual;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertLess.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertLess.js
new file mode 100644
index 0000000000000000000000000000000000000000..17e84b0abaeb20804048a5a15c19e0603634846d
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertLess.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertLess(actualValue, expected) {
+ return {
+ pass: (actualValue) < expected[0],
+ message: (actualValue) + ' is not less than ' + expected[0]
+ };
+}
+
+export default assertLess;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertLessOrEqual.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertLessOrEqual.js
new file mode 100644
index 0000000000000000000000000000000000000000..f754f97ffa9d24e7852efe2423a1dd35d448af82
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertLessOrEqual.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertLessOrEqual(actualValue, expected) {
+ return {
+ pass: (actualValue) <= expected[0],
+ message: (actualValue) + ' is not less than ' + expected[0]
+ };
+}
+
+export default assertLessOrEqual;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertNaN.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertNaN.js
new file mode 100644
index 0000000000000000000000000000000000000000..8d45d6a93b86c5ed325a68b32ff014835993a58e
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertNaN.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertNaN(actualValue) {
+ return {
+ pass: actualValue !== actualValue,
+ message: 'expect NaN, actualValue is ' + actualValue
+ };
+}
+
+export default assertNaN;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertNegUnlimited.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertNegUnlimited.js
new file mode 100644
index 0000000000000000000000000000000000000000..ceac555afc826e057970e6cfe9c73b322c672aa2
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertNegUnlimited.js
@@ -0,0 +1,23 @@
+/*
+* Copyright (c) 2022 Huawei Device Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+function assertNegUnlimited(actualValue) {
+ return {
+ pass: actualValue === Number.NEGATIVE_INFINITY,
+ message: 'Expected actualValue not to be -Infinity. actualValue is,' + actualValue
+ };
+}
+
+export default assertNegUnlimited;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertNull.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertNull.js
new file mode 100644
index 0000000000000000000000000000000000000000..53a7bad827323a98d3302a4e7eea679551b459c5
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertNull.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertNull(actualValue) {
+ return {
+ pass: (actualValue) === null,
+ message: 'expect null, actualValue is ' + (actualValue)
+ };
+}
+
+export default assertNull;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPosUnlimited.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPosUnlimited.js
new file mode 100644
index 0000000000000000000000000000000000000000..6e68c0e2b6c499f4dc3dd56c13e9ea1073a3c54c
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPosUnlimited.js
@@ -0,0 +1,23 @@
+/*
+* Copyright (c) 2022 Huawei Device Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+function assertPosUnlimited(actualValue) {
+ return {
+ pass: actualValue === Number.POSITIVE_INFINITY,
+ message: 'Expected actualValue is POSITIVE_INFINITY. actualValue is,' + actualValue
+ };
+}
+
+export default assertPosUnlimited;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsPending.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsPending.js
new file mode 100644
index 0000000000000000000000000000000000000000..7e2ca2ce14d50c39554fc1157d6d4eb9329d5c39
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsPending.js
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import isPromiseLike from './isPromiseLike';
+
+function assertPromiseIsPending(actualPromise) {
+ if (!isPromiseLike(actualPromise)) {
+ return Promise.reject().then(function () {
+ }, function () {
+ return {pass: false, message: 'Expected not be called on a promise.'};
+ });
+ }
+ const helper = {};
+ return Promise.race([actualPromise, Promise.resolve(helper)]).then(
+ function (got) {
+ return helper === got ? {pass: true, message: 'actualValue is isPending'}
+ : {
+ pass: false,
+ message: 'expect isPending, actualValue is resolve'
+ };
+ },
+ function () {
+ return {
+ pass: false
+ , message: 'expect isPending, actualValue is reject'
+ };
+ });
+}
+
+export default assertPromiseIsPending;
\ No newline at end of file
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejected.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejected.js
new file mode 100644
index 0000000000000000000000000000000000000000..eb8e65c7d70d5750a9ccebb55c2cf5049cf144fc
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejected.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import isPromiseLike from './isPromiseLike';
+
+function assertPromiseIsRejected(actualPromise) {
+ if (!isPromiseLike(actualPromise)) {
+ return Promise.reject().then(function () {
+ }, function () {
+ return {pass: false, message: 'Expected not be called on a promise.'};
+ });
+ }
+ const helper = {};
+ return Promise.race([actualPromise, Promise.resolve(helper)]).then(
+ function (got) {
+ return {
+ pass: false,
+ message: 'expect isRejected, but actualValue is '
+ + (helper === got ? 'isPending' : 'resolve')
+ };
+ },
+ function () {
+ return {pass: true, message: 'actualValue is isRejected'};
+ }
+ );
+}
+
+export default assertPromiseIsRejected;
\ No newline at end of file
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWith.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWith.js
new file mode 100644
index 0000000000000000000000000000000000000000..48eaf7859279a70ea2ad85509296b5da1c7b69f9
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWith.js
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import isPromiseLike from './isPromiseLike';
+
+function assertPromiseIsRejectedWith(actualPromise, expectedValue) {
+
+ if (!isPromiseLike(actualPromise)) {
+ return Promise.reject().then(function () {
+ }, function () {
+ return {pass: false, message: 'Expected not be called on a promise.'};
+ });
+ }
+
+ function tips(passed) {
+ return ('Expected a promise ' + (passed ? 'not ' : '') +
+ 'to be rejected with ' + JSON.stringify(expectedValue[0]));
+ }
+
+ const helper = {};
+ return Promise.race([actualPromise, Promise.resolve(helper)]).then(
+ function (got) {
+ return {
+ pass: false,
+ message: tips(false) + ' but actualValue is '
+ + (helper === got ? 'isPending' : 'resolve')
+ };
+ },
+ function (actualValue) {
+ if (JSON.stringify(actualValue) == JSON.stringify(expectedValue[0])) {
+ return {
+ pass: true,
+ message: 'actualValue was rejected with ' + JSON.stringify(actualValue) + '.'
+ };
+ } else {
+ return {
+ pass: false,
+ message: tips(false) + ' but it was rejected with ' + JSON.stringify(actualValue) + '.'
+ };
+ }
+ }
+ );
+}
+
+export default assertPromiseIsRejectedWith;
\ No newline at end of file
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWithError.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWithError.js
new file mode 100644
index 0000000000000000000000000000000000000000..20f236fc11dd66f270322efa12a1b3f6b543407c
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWithError.js
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import isPromiseLike from './isPromiseLike';
+
+function assertPromiseIsRejectedWithError(actualPromise, expectedValue) {
+ if (!isPromiseLike(actualPromise)) {
+ return Promise.reject().then(function () {
+ }, function () {
+ return {pass: false, message: 'Expected not be called on a promise.'};
+ });
+ }
+ const helper = {};
+ return Promise.race([actualPromise, Promise.resolve(helper)]).then(
+ function (got) {
+ return {
+ pass: false,
+ message: 'Expected a promise to be rejected but actualValue is '
+ + (helper === got ? 'isPending' : 'resolve')
+ };
+ },
+ function (actualValue) {
+ return matchError(actualValue, expectedValue);
+ }
+ );
+
+}
+
+function matchError(actualValue, expectedValue) {
+ if (expectedValue.length == 1 && typeof expectedValue[0] === 'function') {
+ if (expectedValue[0].name === actualValue.__proto__.name) {
+ return {pass: true, message: 'actual error type is ' + actualValue.name + '.'};
+ }
+ return {pass: false, message: `except error type is ${expectedValue[0].name},but actual is ${actualValue.name}.`};
+ }
+
+ if (expectedValue.length == 1 && typeof expectedValue[0] === 'string') {
+ if (expectedValue[0] === actualValue.message) {
+ return {pass: true, message: `actual error message is ${actualValue.message}.`};
+ }
+ return {pass: false, message: `except error message ${expectedValue[0]},but actual is ${actualValue.message}.`};
+ }
+
+ if (expectedValue.length == 1) {
+ return {pass: false, message: 'When only one parameter, it should be error type or error message.'};
+ }
+
+ if (expectedValue.length == 2 && typeof expectedValue[0] === 'function' && expectedValue[0].name === actualValue.name) {
+ if (typeof expectedValue[1] === 'string' && actualValue.message === expectedValue[1]) {
+ return {pass: true, message: 'actual error message is ' + actualValue.message + '.'};
+ }
+ return {pass: false, message: `except error message is ${expectedValue[1]},but actual is ${actualValue.message}.`};
+ }
+
+ if (expectedValue.length == 2 && typeof expectedValue[0] === 'function' && expectedValue[0].name !== actualValue.name) {
+ if (typeof expectedValue[1] === 'string' && actualValue.message === expectedValue[1]) {
+ return {pass: false, message: `except error type is ${expectedValue[0].name},but actual is ${actualValue.name}.`};
+ }
+ return {pass: false, message: 'except error type and message are incorrect.'};
+ }
+ if (expectedValue.length > 2) {
+ return {pass: false, message: 'Up to two parameters are supported.'};
+ }
+}
+
+export default assertPromiseIsRejectedWithError;
\ No newline at end of file
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolved.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolved.js
new file mode 100644
index 0000000000000000000000000000000000000000..855426ca79e5002428e53d4fcb5f843cdf7119f7
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolved.js
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import isPromiseLike from './isPromiseLike';
+
+function assertPromiseIsResolved(actualPromise) {
+ if (!isPromiseLike(actualPromise)) {
+ return Promise.reject().then(function () {
+ }, function () {
+ return {pass: false, message: 'Expected not be called on a promise.'};
+ });
+ }
+
+ const helper = {};
+ return Promise.race([actualPromise, Promise.resolve(helper)]).then(
+ function (got) {
+ return helper === got ? {
+ pass: false,
+ message: 'expect resolve, actualValue is isPending'
+ }
+ : {pass: true, message: 'actualValue is isResolved'};
+ },
+ function (rej) {
+ return {
+ pass: false,
+ message: 'Expected a promise to be resolved but it was ' +
+ 'rejected with ' + JSON.stringify(rej) + '.'
+ };
+ }
+ );
+}
+
+export default assertPromiseIsResolved;
\ No newline at end of file
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolvedWith.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolvedWith.js
new file mode 100644
index 0000000000000000000000000000000000000000..d5eb01e32491b281a1e1d650a307723253a61e39
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolvedWith.js
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import isPromiseLike from './isPromiseLike';
+
+function assertPromiseIsResolvedWith(actualPromise, expectedValue) {
+ if (!isPromiseLike(actualPromise)) {
+ return Promise.reject().then(function () {
+ }, function () {
+ return {pass: false, message: 'Expected not be called on a promise.'};
+ });
+ }
+
+ function tips(passed) {
+ return (
+ 'Expected a promise ' + (passed ? 'not ' : '') +
+ 'to be resolved with ' + JSON.stringify(expectedValue[0]));
+ }
+
+ const helper = {};
+ return Promise.race([actualPromise, Promise.resolve(helper)]).then(
+ function (got) {
+ if (helper === got) {
+ return {pass: false, message: 'expect resolve, actualValue is isPending'};
+ }
+ if (JSON.stringify(got) == JSON.stringify(expectedValue[0])) {
+ return {
+ pass: true,
+ message: 'actualValue was resolved with ' + JSON.stringify(got) + '.'
+ };
+ }
+ return {
+ pass: false,
+ message: tips(false) + ' but it was resolved with ' +
+ JSON.stringify(got) + '.'
+ };
+ },
+ function (rej) {
+ return {
+ pass: false,
+ message: tips(false) + ' but it was rejected with ' + JSON.stringify(rej) + '.'
+ };
+ }
+ );
+}
+
+export default assertPromiseIsResolvedWith;
\ No newline at end of file
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertThrowError.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertThrowError.js
new file mode 100644
index 0000000000000000000000000000000000000000..749cab0daee3f156909f60c9375146c23d7aa322
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertThrowError.js
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertThrowError(actualValue, expected) {
+ let result = false;
+ let err;
+ if (typeof actualValue !== 'function') {
+ throw new Error('actualValue is not a function');
+ }
+ try {
+ actualValue();
+ return {
+ pass: result,
+ message: ' An error is not thrown while it is expected!'
+ };
+ } catch (e) {
+ err = e;
+ }
+
+ if (err instanceof Error) {
+ console.log(err.message);
+ if (err.message == expected[0]) {
+ result = true;
+ }
+ }
+ return {
+ pass: result,
+ message: 'expected throw failed , ' + err.message + ' is not ' + expected[0]
+ };
+}
+
+export default assertThrowError;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertUndefined.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertUndefined.js
new file mode 100644
index 0000000000000000000000000000000000000000..61f092d715dd1630297518b59ff13ef0940991e1
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/assertUndefined.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertUndefined(actualValue) {
+ return {
+ pass: undefined === (actualValue),
+ message: 'expect Undefined, actualValue is ' + (actualValue)
+ };
+}
+
+export default assertUndefined;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/DeepTypeUtils.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/DeepTypeUtils.js
new file mode 100644
index 0000000000000000000000000000000000000000..627fb3b3ae7e315808b5ee2927d4bfbf17cc64b2
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/DeepTypeUtils.js
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class DeepTypeUtils {
+ static getType_(value) {
+ return Object.prototype.toString.apply(value);
+ }
+ static isA_(typeName, value) {
+ return this.getType_(value) === '[object ' + typeName + ']';
+ }
+ static isAsymmetricEqualityTester_(obj) {
+ return obj ? this.isA_('Function', obj.asymmetricMatch) : false;
+ }
+
+ /**
+ * 是否是function
+ * @param value
+ */
+ static isFunction_(value) {
+ return this.isA_('Function', value);
+ }
+
+ /**
+ * 是否是undefined
+ * @param obj
+ */
+ static isUndefined(obj) {
+ return obj === void 0;
+ }
+
+ /**
+ * 是否是Node
+ * @param obj
+ */
+ static isDomNode(obj) {
+ return obj !== null &&
+ typeof obj === 'object' &&
+ typeof obj.nodeType === 'number' &&
+ typeof obj.nodeName === 'string';
+ }
+
+ /**
+ * 是否是promise对象
+ * @param obj
+ */
+ static isPromise (obj) {
+ return !!obj && obj.constructor === Promise;
+ };
+ /**
+ * 是否是map对象
+ * @param obj
+ */
+ static isMap(obj) {
+ return (
+ obj !== null &&
+ typeof obj !== 'undefined' &&
+ obj.constructor === Map
+ );
+ }
+
+ /**
+ * 是否是set对象
+ * @param obj 对象
+ */
+ static isSet(obj) {
+ return (
+ obj !== null &&
+ typeof obj !== 'undefined' &&
+ obj.constructor === Set
+ );
+ }
+
+ /**
+ * 对象是否有key属性
+ * @param obj 对象
+ * @param key 对象属性名称
+ */
+ static has(obj, key) {
+ return Object.prototype.hasOwnProperty.call(obj, key);
+ }
+
+ /**
+ * 获取对象的自有属性
+ * @param obj 对象
+ * @param isArray 是否是数组,[object Array]
+ */
+ static keys(obj, isArray) {
+ const extraKeys = [];
+ // 获取对象所有属性
+ const allKeys = this.getAllKeys(obj);
+ if (!isArray) {
+ return allKeys;
+ }
+ if (allKeys.length === 0) {
+ return allKeys;
+ }
+ for (const k of allKeys) {
+ if (typeof k === 'symbol' || !/^[0-9]+$/.test(k)) {
+ extraKeys.push(k);
+ }
+ }
+ return extraKeys;
+ }
+
+ /**
+ * 获取obj对象的所有属性
+ * @param obj obj对象
+ */
+ static getAllKeys(obj) {
+ const keys = [];
+ for (let key in obj) {
+ if(this.has(obj, key)) {
+ keys.push(key);
+ }
+ }
+ const symbols = Object.getOwnPropertySymbols(obj);
+ for (const sym of symbols) {
+ if (obj.propertyIsEnumerable(sym)) {
+ keys.push(sym);
+ }
+ }
+ return keys;
+ }
+
+}
+export default DeepTypeUtils;
\ No newline at end of file
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/assertDeepEquals.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/assertDeepEquals.js
new file mode 100644
index 0000000000000000000000000000000000000000..482e28e6af45482f8c2d9d0f61130730b07eba70
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/assertDeepEquals.js
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import DeepTypeUtils from './DeepTypeUtils'
+function assertDeepEquals(actualValue, expected) {
+ console.log('actualValue:' + actualValue + ',expected:' + expected[0]);
+ let result = eq(actualValue, expected[0],[], [])
+ let msg = logMsg(actualValue, expected[0]);
+ return {
+ pass: result,
+ message: msg
+ };
+}
+
+/**
+ * 获取失败显示日志
+ * @param actualValue 实际对象
+ * @param expected 期待比较对象
+ */
+function logMsg(actualValue, expected) {
+ // 获取a的对象名称
+ const aClassName = Object.prototype.toString.call(actualValue);
+ const bClassName = Object.prototype.toString.call(expected);
+ let actualMsg;
+ let expectMsg;
+ if(aClassName == "[object Function]") {
+ actualMsg = "actualValue Function"
+ }else if(aClassName == "[object Promise]") {
+ actualMsg = "actualValue Promise"
+ }else if(aClassName == "[object Set]" || aClassName == "[object Map]") {
+ actualMsg = JSON.stringify(Array.from(actualValue));;
+ }else if(aClassName == "[object RegExp]") {
+ actualMsg = JSON.stringify(actualValue.source.replace("\\",""));;
+ }else if(aClassName == "[object BigInt]") {
+ actualMsg = actualValue;
+ }
+ else{
+ actualMsg = JSON.stringify(actualValue);
+ }
+ if(bClassName == "[object Function]") {
+ expectMsg = "expected Function"
+ }else if(bClassName == "[object Promise]") {
+ expectMsg = "expected Promise"
+ }else if(bClassName == "[object Set]" || bClassName == "[object Map]") {
+ expectMsg = JSON.stringify(Array.from(expected));
+ }else if(bClassName == "[object RegExp]") {
+ expectMsg = JSON.stringify(expected.source.replace("\\",""));;
+ }else if(bClassName == "[object BigInt]") {
+ expectMsg = expected;
+ }
+ else{
+ expectMsg = JSON.stringify(expected);
+ }
+ return actualMsg + " is not deep equal " + expectMsg;
+}
+
+function eq(a, b, aStack, bStack) {
+ let result = true;
+ console.log('a is:' + a + ',b is:' + b);
+ const asymmetricResult = asymmetricMatch_(a,b);
+ if (!DeepTypeUtils.isUndefined(asymmetricResult)) {
+ return asymmetricResult;
+ }
+
+ if (a instanceof Error && b instanceof Error) {
+ result = a.message == b.message;
+ return result;
+ }
+
+ if (a === b) {
+ result = a !== 0 || 1 / a == 1 / b;
+ return result;
+ }
+
+ if (a === null || b === null) {
+ result = a === b;
+ return result;
+ }
+ // 获取a的对象名称
+ const aClassName = Object.prototype.toString.call(a);
+ const bClassName = Object.prototype.toString.call(b);
+ console.log('aClassName is:' + aClassName);
+ console.log('bClassName is:' + bClassName);
+ // 不同类型不同对象
+ if (aClassName != bClassName) {
+ return false;
+ }
+ // 俩个string对象
+ if(aClassName === '[object String]') {
+ result = a == String(b);
+ return result;
+ }
+ // 俩个Number对象
+ if(aClassName === '[object Number]') {
+ result = a != +a ? b != +b : a === 0 && b === 0 ? 1 / a == 1 / b : a == +b;
+ return result;
+ }
+
+ if(aClassName === '[object Date]' || aClassName === '[object Boolean]') {
+ result = +a == +b;
+ return result;
+ }
+
+ // 数组
+ if(aClassName === '[object ArrayBuffer]') {
+ return eq(new Uint8Array(a), new Uint8Array(b), aStack, bStack);
+ }
+
+ // 正则表达式
+ if(aClassName === '[object RegExp]') {
+ return (
+ a.source == b.source &&
+ a.global == b.global &&
+ a.multiline == b.multiline &&
+ a.ignoreCase == b.ignoreCase
+ );
+ }
+
+ if (typeof a != 'object' || typeof b != 'object') {
+ return false;
+ }
+
+ const aIsDomNode = DeepTypeUtils.isDomNode(a);
+ const bIsDomNode = DeepTypeUtils.isDomNode(b);
+ if (aIsDomNode && bIsDomNode) {
+ // At first try to use DOM3 method isEqualNode
+ result = a.isEqualNode(b);
+ return result;
+ }
+ if (aIsDomNode || bIsDomNode) {
+ return false;
+ }
+ const aIsPromise = DeepTypeUtils.isPromise(a);
+ const bIsPromise = DeepTypeUtils.isPromise(b);
+ if (aIsPromise && bIsPromise) {
+ return a === b;
+ }
+ let length = aStack.length;
+ while (length--) {
+ if (aStack[length] == a) {
+ return bStack[length] == b;
+ }
+ }
+ aStack.push(a);
+ bStack.push(b);
+ let size = 0;
+
+ // 都是数组
+ if(aClassName == '[object Array]') {
+ const aLength = a.length;
+ const bLength = b.length;
+ if (aLength !== bLength) {
+ // 数组长度不同,不是同一个对象
+ return false;
+ }
+ for (let i = 0; i < aLength || i < bLength; i++) {
+ // 递归每一个元素是否相同
+ result = eq(i < aLength ? a[i] : void 0, i < bLength ? b[i] : void 0, aStack, bStack) && result;
+ }
+ if (!result) {
+ return false;
+ }
+ } else if(DeepTypeUtils.isMap(a) && DeepTypeUtils.isMap(b)) {
+ if (a.size != b.size) {
+ return false;
+ }
+ const keysA = [];
+ const keysB = [];
+ a.forEach(function(valueA, keyA) {
+ keysA.push(keyA);
+ });
+ b.forEach(function(valueB, keyB) {
+ keysB.push(keyB);
+ });
+ const mapKeys = [keysA, keysB];
+ const cmpKeys = [keysB, keysA];
+ for (let i = 0; result && i < mapKeys.length; i++) {
+ const mapIter = mapKeys[i];
+ const cmpIter = cmpKeys[i];
+
+ for (let j = 0; result && j < mapIter.length; j++) {
+ const mapKey = mapIter[j];
+ const cmpKey = cmpIter[j];
+ const mapValueA = a.get(mapKey);
+ let mapValueB;
+ if (
+ DeepTypeUtils.isAsymmetricEqualityTester_(mapKey) ||
+ (DeepTypeUtils.isAsymmetricEqualityTester_(cmpKey) &&
+ eq(mapKey, cmpKey))
+ ) {
+ mapValueB = b.get(cmpKey);
+ } else {
+ mapValueB = b.get(mapKey);
+ }
+ result = eq(mapValueA, mapValueB, aStack, bStack);
+ }
+ }
+ if (!result) {
+ return false;
+ }
+ } else if(DeepTypeUtils.isSet(a) && DeepTypeUtils.isSet(b)) {
+ if (a.size != b.size) {
+ return false;
+ }
+ const valuesA = [];
+ a.forEach(function(valueA) {
+ valuesA.push(valueA);
+ });
+ const valuesB = [];
+ b.forEach(function(valueB) {
+ valuesB.push(valueB);
+ });
+ const setPairs = [[valuesA, valuesB], [valuesB, valuesA]];
+ const stackPairs = [[aStack, bStack], [bStack, aStack]];
+ for (let i = 0; result && i < setPairs.length; i++) {
+ const baseValues = setPairs[i][0];
+ const otherValues = setPairs[i][1];
+ const baseStack = stackPairs[i][0];
+ const otherStack = stackPairs[i][1];
+ for (const baseValue of baseValues) {
+ let found = false;
+ for (let j = 0; !found && j < otherValues.length; j++) {
+ const otherValue = otherValues[j];
+ const prevStackSize = baseStack.length;
+ // 深度比较对象
+ found = eq(baseValue, otherValue, baseStack, otherStack);
+ if (!found && prevStackSize !== baseStack.length) {
+ baseStack.splice(prevStackSize);
+ otherStack.splice(prevStackSize);
+ }
+ }
+ result = result && found;
+ }
+ }
+ if (!result) {
+ return false;
+ }
+ } else {
+ const aCtor = a.constructor,
+ bCtor = b.constructor;
+ if (
+ aCtor !== bCtor &&
+ DeepTypeUtils.isFunction_(aCtor) &&
+ DeepTypeUtils.isFunction_(bCtor) &&
+ a instanceof aCtor &&
+ b instanceof bCtor &&
+ !(aCtor instanceof aCtor && bCtor instanceof bCtor)
+ ) {
+ return false;
+ }
+ }
+
+ // 获取对象所有的属性集合
+ const aKeys = DeepTypeUtils.keys(a, aClassName == '[object Array]');
+ size = aKeys.length;
+
+ // 俩个对象属性长度不一致, 俩对象不相同
+ if (DeepTypeUtils.keys(b, bClassName == '[object Array]').length !== size) {
+ return false;
+ }
+
+ // 俩对象属性数量相同, 递归比较每个属性值得值
+ for (const key of aKeys) {
+ console.log('key is:' + key);
+ // b 没有 key 属性
+ if(!DeepTypeUtils.has(b, key)) {
+ result = false;
+ continue;
+ }
+ if (!eq(a[key], b[key], aStack, bStack)) {
+ result = false;
+ }
+ }
+ if (!result) {
+ return false;
+ }
+ aStack.pop();
+ bStack.pop();
+ return result;
+}
+
+function asymmetricMatch_(a, b) {
+ const asymmetricA = DeepTypeUtils.isAsymmetricEqualityTester_(a);
+ const asymmetricB = DeepTypeUtils.isAsymmetricEqualityTester_(b);
+
+ if (asymmetricA === asymmetricB) {
+ return undefined;
+ }
+
+}
+
+/**
+ * 获取对象的自有属性
+ *
+ * @param obj 对象
+ * @param isArray 是否是一个数组
+ */
+function keys(obj, isArray) {
+ const keys = [];
+
+}
+
+export default assertDeepEquals;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/isPromiseLike.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/isPromiseLike.js
new file mode 100644
index 0000000000000000000000000000000000000000..015ab19a2a0c4872d7cb490b61f8e1dd6a8ac90b
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/assert/isPromiseLike.js
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function isPromiseLike(obj) {
+ return !!obj && isFunction_(obj.then);
+}
+
+function isFunction_(value) {
+ return isA_('Function', value);
+}
+
+function isA_(typeName, value) {
+ return getType_(value) === '[object ' + typeName + ']';
+}
+
+function getType_(value) {
+ return Object.prototype.toString.apply(value);
+}
+
+export default isPromiseLike;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/config/DataDriver.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/config/DataDriver.js
new file mode 100644
index 0000000000000000000000000000000000000000..639dffc9cdb912f1f33a6ccb61868c9ed7c695bf
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/config/DataDriver.js
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const SUITES_KEY = 'suites';
+const SPECS_KEY = 'items';
+const DESCRIBE_KEY = 'describe';
+const IT_KEY = 'it';
+const PARAMS_KEY = 'params';
+const STRESS_KEY = 'stress';
+
+class ObjectUtils {
+ static get(object, name, defaultValue) {
+ let result = defaultValue;
+ for (const key in object) {
+ if (key === name) {
+ return object[key];
+ }
+ }
+ return result;
+ }
+
+ static has(object, key) {
+ return Object.prototype.hasOwnProperty.call(object, key);
+ }
+}
+
+class DataDriver {
+ constructor(attr) {
+ this.id = 'dataDriver';
+ this.data = attr.data || {};
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ this.suiteService = this.coreContext.getDefaultService('suite');
+ this.specService = this.coreContext.getDefaultService('spec');
+ }
+
+ getSpecParams() {
+ let specParams = [];
+ let suiteDesc = this.suiteService.getCurrentRunningSuite().description;
+ let specDesc = this.specService.getCurrentRunningSpec().description;
+ let suites = ObjectUtils.get(this.data, SUITES_KEY, []);
+ for (const suiteItem of suites) {
+ let describeValue = ObjectUtils.get(suiteItem, DESCRIBE_KEY, '');
+ if (ObjectUtils.has(suiteItem, DESCRIBE_KEY) && (typeof describeValue === 'object') && describeValue.constructor === Array && describeValue.includes(suiteDesc)) {
+ let specs = ObjectUtils.get(suiteItem, SPECS_KEY, []);
+ for (const specItem of specs) {
+ if (ObjectUtils.has(specItem, IT_KEY) && ObjectUtils.get(specItem, IT_KEY) === specDesc) {
+ return ObjectUtils.get(specItem, PARAMS_KEY, specParams);
+ }
+ }
+ }
+ }
+ return specParams;
+ }
+
+ getSuiteParams() {
+ let suiteParams = {};
+ let suiteDesc = this.suiteService.getCurrentRunningSuite().description;
+ let suites = ObjectUtils.get(this.data, SUITES_KEY, []);
+ for (const suiteItem of suites) {
+ let describeValue = ObjectUtils.get(suiteItem, DESCRIBE_KEY, []);
+ if (ObjectUtils.has(suiteItem, DESCRIBE_KEY) && (typeof describeValue === 'object') && describeValue.constructor === Array && describeValue.includes(suiteDesc)) {
+ suiteParams = Object.assign({}, suiteParams, ObjectUtils.get(suiteItem, PARAMS_KEY, suiteParams));
+ }
+ }
+ return suiteParams;
+ }
+
+ getSpecStress(specDesc) {
+ let stress = 1;
+ let suiteDesc = this.suiteService.getCurrentRunningSuite().description;
+ let suites = ObjectUtils.get(this.data, SUITES_KEY, []);
+ for (const suiteItem of suites) {
+ let describeValue = ObjectUtils.get(suiteItem, DESCRIBE_KEY, '');
+ if (ObjectUtils.has(suiteItem, DESCRIBE_KEY) && (typeof describeValue === 'object') && describeValue.constructor === Array && describeValue.includes(suiteDesc)) {
+ let specs = ObjectUtils.get(suiteItem, SPECS_KEY, []);
+ for (const specItem of specs) {
+ if (ObjectUtils.has(specItem, IT_KEY) && ObjectUtils.get(specItem, IT_KEY) === specDesc) {
+ let tempStress = ObjectUtils.get(specItem, STRESS_KEY, stress);
+ return (Number.isInteger(tempStress) && tempStress >= 1) ? tempStress : stress;
+ }
+ }
+ }
+ }
+ return stress;
+ }
+
+ getSuiteStress(suiteDesc) {
+ let stress = 1;
+ let suites = ObjectUtils.get(this.data, SUITES_KEY, []);
+ for (const suiteItem of suites) {
+ let describeValue = ObjectUtils.get(suiteItem, DESCRIBE_KEY, []);
+ if (ObjectUtils.has(suiteItem, DESCRIBE_KEY) && (typeof describeValue === 'object') && describeValue.constructor === Array && describeValue.includes(suiteDesc)) {
+ let tempStress = ObjectUtils.get(suiteItem, STRESS_KEY, stress);
+ return (Number.isInteger(tempStress) && tempStress >= 1) ? tempStress : stress;
+ }
+ }
+ return stress;
+ }
+}
+
+export default DataDriver;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/config/Filter.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/config/Filter.js
new file mode 100644
index 0000000000000000000000000000000000000000..0ca3b4f412353ad0e9fa70bcfe775c905b5e02a9
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/config/Filter.js
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class ClassFilter {
+ constructor(suiteName, itName, params) {
+ this.suiteName = suiteName;
+ this.itName = itName;
+ this.params = params;
+ }
+
+ filterSuite() {
+ return !this.params.split(',').map(item => item.split('#')[0]).map(item => item == this.suiteName).reduce((pre, cur) => pre || cur, false);
+ }
+
+ filterIt() {
+ let classArray = this.params.split(',') || [];
+ let suiteFilterResult = classArray.filter(item => !item.includes('#')).map(item => item == this.suiteName).reduce((pre, cur) => pre || cur, false);
+ let itFilterResult = classArray.filter(item => item.includes('#')).map(item => item == (this.suiteName + '#' + this.itName)).reduce((pre, cur) => pre || cur, false);
+ return !(suiteFilterResult || itFilterResult);
+ }
+}
+
+class NotClassFilter {
+ constructor(suiteName, itName, params) {
+ this.suiteName = suiteName;
+ this.itName = itName;
+ this.params = params;
+ }
+
+ filterSuite() {
+ return this.params.split(',').map(item => item == this.suiteName).reduce((pre, cur) => pre || cur, false);
+ }
+
+ filterIt() {
+ return this.params.split(',').some(item => item == (this.suiteName + '#' + this.itName));
+ }
+}
+
+class SuiteAndItNameFilter {
+ constructor(suiteName, itName, params) {
+ this.suiteName = suiteName;
+ this.itName = itName;
+ this.params = params;
+ }
+
+ filterSuite() {
+ return !this.params.split(',').map(item => item == this.suiteName).reduce((pre, cur) => pre || cur, false);
+ }
+
+ filterIt() {
+ return !this.params.split(',').map(item => item == this.itName).reduce((pre, cur) => pre || cur, false);
+ }
+}
+
+
+class TestTypesFilter {
+ constructor(suiteName, itName, fi, params) {
+ this.suiteName = suiteName;
+ this.itName = itName;
+ this.params = params;
+ this.fi = fi;
+ }
+
+ filterIt() {
+ return !((this.params === (this.fi & this.params)) || this.fi === 0);
+ }
+}
+
+export {ClassFilter, NotClassFilter, SuiteAndItNameFilter, TestTypesFilter};
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/config/configService.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/config/configService.js
new file mode 100644
index 0000000000000000000000000000000000000000..94f4a764b04d1d190e495a53ed09834f2e411bf2
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/config/configService.js
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {ClassFilter, NotClassFilter, SuiteAndItNameFilter, TestTypesFilter} from './Filter';
+import {TAG} from '../../Constant';
+const STRESS_RULE = /^[1-9]\d*$/;
+
+class ConfigService {
+ constructor(attr) {
+ this.id = attr.id;
+ this.supportAsync = false;
+ this.random = false;
+ this.filterValid = [];
+ this.filter = 0;
+ this.flag = false;
+ this.suite = null;
+ this.itName = null;
+ this.testType = null;
+ this.level = null;
+ this.size = null;
+ this.class = null;
+ this.notClass = null;
+ this.timeout = null;
+ // 遇错即停模式配置
+ this.breakOnError = false;
+ // 压力测试配置
+ this.stress = null;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ }
+
+ isNormalInteger(str) {
+ const n = Math.floor(Number(str));
+ return n !== Infinity && String(n) === String(str) && n >= 0;
+ }
+
+ getStress() {
+ if (this.stress === undefined || this.stress === '' || this.stress === null) {
+ return 1;
+ }
+ return !this.stress.match(STRESS_RULE) ? 1 : Number.parseInt(this.stress);
+ }
+
+ basicParamValidCheck(params) {
+ let size = params.size;
+ if (size !== undefined && size !== '' && size !== null) {
+ let sizeArray = ['small', 'medium', 'large'];
+ if (sizeArray.indexOf(size) === -1) {
+ this.filterValid.push('size:' + size);
+ }
+ }
+ let level = params.level;
+ if (level !== undefined && level !== '' && level !== null) {
+ let levelArray = ['0', '1', '2', '3', '4'];
+ if (levelArray.indexOf(level) === -1) {
+ this.filterValid.push('level:' + level);
+ }
+ }
+ let testType = params.testType;
+ if (testType !== undefined && testType !== '' && testType !== null) {
+ let testTypeArray = ['function', 'performance', 'power', 'reliability', 'security',
+ 'global', 'compatibility', 'user', 'standard', 'safety', 'resilience'];
+ if (testTypeArray.indexOf(testType) === -1) {
+ this.filterValid.push('testType:' + testType);
+ }
+ }
+ }
+
+ filterParamValidCheck(params) {
+ let timeout = params.timeout;
+ if (timeout !== undefined && timeout !== '' && timeout !== null) {
+ if (!this.isNormalInteger(timeout)) {
+ this.filterValid.push('timeout:' + timeout);
+ }
+ }
+
+ let paramKeys = ['dryRun', 'random', 'breakOnError', 'coverage'];
+ for (const key of paramKeys) {
+ if (params[key] !== undefined && params[key] !== 'true' && params[key] !== 'false') {
+ this.filterValid.push(`${key}:${params[key]}`);
+ }
+ }
+
+ // 压力测试参数验证,正整数
+ if (params.stress !== undefined && params.stress !== '' && params.stress !== null) {
+ if (!params.stress.match(STRESS_RULE)) {
+ this.filterValid.push('stress:' + params.stress);
+ }
+ }
+
+ let nameRule = /^[A-Za-z]{1}[\w#,.]*$/;
+ let paramClassKeys = ['class', 'notClass'];
+ for (const key of paramClassKeys) {
+ if (params[key] !== undefined && params[key] !== '' && params[key] !== null) {
+ let classArray = params[key].split(',');
+ classArray.forEach(item => !item.match(nameRule) ? this.filterValid.push(`${key}:${params[key]}`) : null);
+ }
+ }
+ }
+
+ setConfig(params) {
+ this.basicParamValidCheck(params);
+ this.filterParamValidCheck(params);
+ try {
+ this.class = params.class;
+ this.notClass = params.notClass;
+ this.flag = params.flag || {flag: false};
+ this.suite = params.suite;
+ this.itName = params.itName;
+ this.filter = params.filter;
+ this.testType = params.testType;
+ this.level = params.level;
+ this.size = params.size;
+ this.timeout = params.timeout;
+ this.dryRun = params.dryRun;
+ this.breakOnError = params.breakOnError;
+ this.random = params.random === 'true' ? true : false;
+ this.stress = params.stress;
+ this.coverage = params.coverage;
+ this.filterParam = {
+ testType: {
+ 'function': 1,
+ 'performance': 1 << 1,
+ 'power': 1 << 2,
+ 'reliability': 1 << 3,
+ 'security': 1 << 4,
+ 'global': 1 << 5,
+ 'compatibility': 1 << 6,
+ 'user': 1 << 7,
+ 'standard': 1 << 8,
+ 'safety': 1 << 9,
+ 'resilience': 1 << 10,
+ },
+ level: {
+ '0': 1 << 24,
+ '1': 1 << 25,
+ '2': 1 << 26,
+ '3': 1 << 27,
+ '4': 1 << 28,
+ },
+ size: {
+ 'small': 1 << 16,
+ 'medium': 1 << 17,
+ 'large': 1 << 18,
+ }
+ };
+ this.parseParams();
+ } catch (err) {
+ console.info(`${TAG}setConfig error: ${err.message}`);
+ }
+ }
+
+ parseParams() {
+ if (this.filter != null) {
+ return;
+ }
+ let testTypeFilter = 0;
+ let sizeFilter = 0;
+ let levelFilter = 0;
+ if (this.testType != null) {
+ testTypeFilter = this.testType.split(',')
+ .map(item => this.filterParam.testType[item] || 0)
+ .reduce((pre, cur) => pre | cur, 0);
+ }
+ if (this.level != null) {
+ levelFilter = this.level.split(',')
+ .map(item => this.filterParam.level[item] || 0)
+ .reduce((pre, cur) => pre | cur, 0);
+ }
+ if (this.size != null) {
+ sizeFilter = this.size.split(',')
+ .map(item => this.filterParam.size[item] || 0)
+ .reduce((pre, cur) => pre | cur, 0);
+ }
+ this.filter = testTypeFilter | sizeFilter | levelFilter;
+ console.info(`${TAG}filter params:${this.filter}`);
+ }
+
+ isCurrentSuite(description) {
+ if (this.suite !== undefined && this.suite !== '' && this.suite !== null) {
+ let suiteArray = this.suite.split(',');
+ return suiteArray.indexOf(description) !== -1;
+ }
+ return false;
+ }
+
+ filterSuite(currentSuiteName) {
+ let filterArray = [];
+ if (this.suite !== undefined && this.suite !== '' && this.suite !== null) {
+ filterArray.push(new SuiteAndItNameFilter(currentSuiteName, '', this.suite));
+ }
+ if (this.class !== undefined && this.class !== '' && this.class !== null) {
+ filterArray.push(new ClassFilter(currentSuiteName, '', this.class));
+ }
+ if (this.notClass !== undefined && this.notClass !== '' && this.notClass !== null) {
+ filterArray.push(new NotClassFilter(currentSuiteName, '', this.notClass));
+ }
+
+ let result = filterArray.map(item => item.filterSuite()).reduce((pre, cur) => pre || cur, false);
+ return result;
+ }
+
+ filterDesc(currentSuiteName, desc, fi, coreContext) {
+ let filterArray = [];
+ if (this.itName !== undefined && this.itName !== '' && this.itName !== null) {
+ filterArray.push(new SuiteAndItNameFilter(currentSuiteName, desc, this.itName));
+ }
+ if (this.class !== undefined && this.class !== '' && this.class !== null) {
+ filterArray.push(new ClassFilter(currentSuiteName, desc, this.class));
+ }
+ if (this.notClass !== undefined && this.notClass !== '' && this.notClass !== null) {
+ filterArray.push(new NotClassFilter(currentSuiteName, desc, this.notClass));
+ }
+ if (typeof (this.filter) !== 'undefined' && this.filter !== 0 && fi !== 0) {
+ filterArray.push(new TestTypesFilter('', '', fi, this.filter));
+ }
+ let result = filterArray.map(item => item.filterIt()).reduce((pre, cur) => pre || cur, false);
+ return result;
+ }
+
+ isRandom() {
+ return this.random || false;
+ }
+
+ isBreakOnError() {
+ return this.breakOnError !== true ? false : true;
+ }
+
+ setSupportAsync(value) {
+ this.supportAsync = value;
+ }
+
+ isSupportAsync() {
+ return this.supportAsync;
+ }
+
+ translateParams(parameters) {
+ const keySet = new Set([
+ '-s class', '-s notClass', '-s suite', '-s itName',
+ '-s level', '-s testType', '-s size', '-s timeout',
+ '-s dryRun', '-s random', '-s breakOnError', '-s stress',
+ '-s coverage', 'class', 'notClass', 'suite', 'itName',
+ 'level', 'testType', 'size', 'timeout', 'dryRun', 'random',
+ 'breakOnError', 'stress', 'coverage'
+ ]);
+ let targetParams = {};
+ for (const key in parameters) {
+ if (keySet.has(key)) {
+ var newKey = key.replace("-s ", "");
+ targetParams[newKey] = parameters[key];
+ }
+ }
+ return targetParams;
+ }
+ translateParamsToString(parameters) {
+ const keySet = new Set([
+ '-s class', '-s notClass', '-s suite', '-s itName',
+ '-s level', '-s testType', '-s size', '-s timeout',
+ '-s dryRun', '-s random', '-s breakOnError', '-s stress',
+ '-s coverage', 'class', 'notClass', 'suite', 'itName',
+ 'level', 'testType', 'size', 'timeout', 'dryRun', 'random',
+ 'breakOnError', 'stress', 'coverage'
+ ]);
+ let targetParams = '';
+ for (const key in parameters) {
+ if (keySet.has(key)) {
+ targetParams += ' ' + key + ' ' + parameters[key];
+ }
+ }
+ return targetParams.trim();
+ }
+
+ execute() {
+ }
+}
+
+export {
+ ConfigService
+};
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/coverage/coverageCollect.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/coverage/coverageCollect.js
new file mode 100644
index 0000000000000000000000000000000000000000..632a6820503dcdec7646add5ee6a2c6b3c6227bb
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/coverage/coverageCollect.js
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import SysTestKit from "../kit/SysTestKit";
+
+export async function collectCoverageData() {
+ if (globalThis.__coverage__ === undefined) {
+ return;
+ }
+ const strJson = JSON.stringify(globalThis.__coverage__);
+ const strLen = strJson.length;
+ const maxLen = 500;
+ const maxCount = Math.floor(strLen / maxLen);
+ const OHOS_REPORT_COVERAGE_DATA = 'OHOS_REPORT_COVERAGE_DATA:';
+ for (let count = 0; count <= maxCount; count++) {
+ console.info(`${OHOS_REPORT_COVERAGE_DATA} ${strJson.substring(count * maxLen, (count + 1) * maxLen)}`);
+ await SysTestKit.print(`${OHOS_REPORT_COVERAGE_DATA} ${strJson.substring(count * maxLen, (count + 1) * maxLen)}`);
+ }
+}
\ No newline at end of file
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/kit/SysTestKit.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/kit/SysTestKit.js
new file mode 100644
index 0000000000000000000000000000000000000000..65d063c7d56a85f64967103922a6b261bd79c0b8
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/kit/SysTestKit.js
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {TAG} from '../../Constant';
+
+export default class SysTestKit {
+
+ static delegator = null;
+ static systemTime = null;
+
+ constructor() {
+ this.id = 'sysTestKit';
+ this.index = 0;
+ }
+
+ static actionStart(tag) {
+ console.info(`${TAG}${JSON.stringify(tag)}`);
+ var message = '\n' + 'OHOS_REPORT_ACTIONSTART: ' + JSON.stringify(tag) + '\n';
+ SysTestKit.print(message);
+ console.info(`${TAG}${JSON.stringify(tag)} actionStart print success`);
+ }
+
+ static actionEnd(tag) {
+ console.info(`${TAG}${JSON.stringify(tag)}`);
+ var message = '\n' + 'OHOS_REPORT_ACTIONEND: ' + JSON.stringify(tag) + '\n';
+ SysTestKit.print(message);
+ console.info(`${TAG}${JSON.stringify(tag)} actionEnd print success`);
+ }
+
+ static async existKeyword(keyword, timeout) {
+ let reg = new RegExp(/^[a-zA-Z0-9]{1,}$/);
+ if (!reg.test(keyword)) {
+ throw new Error('keyword must contain more than one string, and only letters and numbers are supported.');
+ }
+ timeout = timeout || 4;
+
+ let searchResult = false;
+ let cmd = 'hilog -x | grep -i \'' + keyword + '\' | wc -l';
+ await executePromise(cmd, timeout).then((data) => {
+ searchResult = data;
+ });
+ return searchResult;
+ }
+ static async print(message) {
+ if ('printSync' in SysTestKit.delegator) {
+ console.debug(`${TAG}printSync called ...`);
+ SysTestKit.delegator.printSync(message);
+ } else {
+ await SysTestKit.delegator.print(message);
+ }
+ }
+
+ static async getRealTime() {
+ let currentTime = new Date().getTime();
+ if (SysTestKit.systemTime !== null && SysTestKit.systemTime !== undefined) {
+ await SysTestKit.systemTime.getRealTime().then((time) => {
+ console.info(`${TAG}systemTime.getRealTime success data: ${JSON.stringify(time)}`);
+ currentTime = time;
+ }).catch((error) => {
+ console.error(`${TAG}failed to systemTime.getRealTime because ${JSON.stringify(error)}`);
+ });
+ }
+ return currentTime;
+ }
+}
+
+function executePromise(cmd, timeout) {
+ return new Promise((resolve, reject) => {
+ SysTestKit.delegator.executeShellCommand(cmd, timeout,
+ (error, data) => {
+ console.info(`${TAG}existKeyword CallBack: err : ${JSON.stringify(error)}`);
+ console.info(`${TAG}existKeyword CallBack: data : ${JSON.stringify(data)}`);
+ resolve(parseInt(data.stdResult) > 3 ? true : false);
+ });
+ });
+}
\ No newline at end of file
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/mock/ArgumentMatchers.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/mock/ArgumentMatchers.js
new file mode 100644
index 0000000000000000000000000000000000000000..6a9d7aac464e95383ea31385284b6603c34e084c
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/mock/ArgumentMatchers.js
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class ArgumentMatchers {
+ ANY = "";
+ ANY_STRING = "";
+ ANY_BOOLEAN = "";
+ ANY_NUMBER = "";
+ ANY_OBJECT = "";
+ ANY_FUNCTION = "";
+ MATCH_REGEXS = "";
+
+ static any() {
+ }
+
+ static anyString() {
+ }
+
+ static anyBoolean() {
+ }
+
+ static anyNumber() {
+ }
+
+ static anyObj() {
+ }
+
+ static anyFunction() {
+ }
+
+ static matchRegexs() {
+ let regex = arguments[0];
+ if (ArgumentMatchers.isRegExp(regex)) {
+ return regex;
+ }
+ throw Error("not a regex");
+ }
+
+ static isRegExp(value) {
+ return Object.prototype.toString.call(value) === "[object RegExp]";
+ }
+
+ matcheReturnKey() {
+ let arg = arguments[0];
+ let regex = arguments[1];
+ let stubSetKey = arguments[2];
+
+ if (stubSetKey && stubSetKey == this.ANY) {
+ return this.ANY;
+ }
+
+ if (typeof arg === "string" && !regex) {
+ return this.ANY_STRING;
+ }
+
+ if (typeof arg === "boolean" && !regex) {
+ return this.ANY_BOOLEAN;
+ }
+
+ if (typeof arg === "number" && !regex) {
+ return this.ANY_NUMBER;
+ }
+
+ if (typeof arg === "object" && !regex) {
+ return this.ANY_OBJECT;
+ }
+
+ if (typeof arg === "function" && !regex) {
+ return this.ANY_FUNCTION;
+ }
+
+ if (typeof arg === "string" && regex) {
+ return regex.test(arg);
+ }
+
+ return null;
+ }
+
+ matcheStubKey() {
+ let key = arguments[0];
+
+ if (key === ArgumentMatchers.any) {
+ return this.ANY;
+ }
+
+ if (key === ArgumentMatchers.anyString) {
+ return this.ANY_STRING;
+ }
+ if (key === ArgumentMatchers.anyBoolean) {
+ return this.ANY_BOOLEAN;
+ }
+ if (key === ArgumentMatchers.anyNumber) {
+ return this.ANY_NUMBER;
+ }
+ if (key === ArgumentMatchers.anyObj) {
+ return this.ANY_OBJECT;
+ }
+ if (key === ArgumentMatchers.anyFunction) {
+ return this.ANY_FUNCTION;
+ }
+
+ if (ArgumentMatchers.isRegExp(key)) {
+ return key;
+ }
+
+ return null;
+ }
+}
+
+export default ArgumentMatchers;
\ No newline at end of file
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/mock/ExtendInterface.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/mock/ExtendInterface.js
new file mode 100644
index 0000000000000000000000000000000000000000..c6a866a6df662ad10a7f6869dcbc2381fa47bcdc
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/mock/ExtendInterface.js
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class ExtendInterface {
+ constructor(mocker) {
+ this.mocker = mocker;
+ }
+
+ stub() {
+ this.params = arguments;
+ return this;
+ }
+
+ stubMockedCall(returnInfo) {
+ this.mocker.stubApply(this, this.params, returnInfo);
+ }
+
+ afterReturn(value) {
+ this.stubMockedCall(function () {
+ return value;
+ });
+ }
+
+ afterReturnNothing() {
+ this.stubMockedCall(function () {
+ return undefined;
+ });
+ }
+
+ afterAction(action) {
+ this.stubMockedCall(action);
+ }
+
+ afterThrow(msg) {
+ this.stubMockedCall(function () {
+ throw msg;
+ });
+ }
+
+ clear() {
+ this.mocker.clear();
+ }
+}
+
+export default ExtendInterface;
\ No newline at end of file
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/mock/MockKit.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/mock/MockKit.js
new file mode 100644
index 0000000000000000000000000000000000000000..1bd83be8a3eb8435486013fe1be5947e0fbe574e
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/mock/MockKit.js
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import ExtendInterface from "./ExtendInterface";
+import VerificationMode from "./VerificationMode";
+import ArgumentMatchers from "./ArgumentMatchers";
+
+class MockKit {
+
+ constructor() {
+ this.mFunctions = [];
+ this.stubs = new Map();
+ this.recordCalls = new Map();
+ this.currentSetKey = new Map();
+ this.mockObj = null;
+ this.recordMockedMethod = new Map();
+ }
+
+ init() {
+ this.reset();
+ }
+
+ reset() {
+ this.mFunctions = [];
+ this.stubs = {};
+ this.recordCalls = {};
+ this.currentSetKey = new Map();
+ this.mockObj = null;
+ this.recordMockedMethod = new Map();
+ }
+
+ clearAll() {
+ this.reset();
+ var props = Object.keys(this);
+ for (var i = 0; i < props.length; i++) {
+ delete this[props[i]];
+ }
+
+ var props = Object.getOwnPropertyNames(this);
+ for (var i = 0; i < props.length; i++) {
+ delete this[props[i]];
+ }
+ for (var key in this) {
+ delete this[key];
+ }
+ }
+
+ clear(obj) {
+ if (!obj) throw Error("Please enter an object to be cleaned");
+ if (typeof (obj) != 'object') throw new Error('Not a object');
+ this.recordMockedMethod.forEach(function (value, key, map) {
+ if (key) {
+ obj[key] = value;
+ }
+ });
+ }
+
+ ignoreMock(obj, method) {
+ if (typeof (obj) != 'object') throw new Error('Not a object');
+ if (typeof (method) != 'function') throw new Error('Not a function');
+ let og = this.recordMockedMethod.get(method.propName);
+ if (og) {
+ obj[method.propName] = og;
+ this.recordMockedMethod.set(method.propName, undefined);
+ }
+ }
+
+ extend(dest, source) {
+ dest["stub"] = source["stub"];
+ dest["afterReturn"] = source["afterReturn"];
+ dest["afterReturnNothing"] = source["afterReturnNothing"];
+ dest["afterAction"] = source["afterAction"];
+ dest["afterThrow"] = source["afterThrow"];
+ dest["stubMockedCall"] = source["stubMockedCall"];
+ dest["clear"] = source["clear"];
+ return dest;
+ }
+
+ stubApply(f, params, returnInfo) {
+ let values = this.stubs.get(f);
+ if (!values) {
+ values = new Map();
+ }
+ let key = params[0];
+ if (typeof key == "undefined") {
+ key = "anonymous-mock-" + f.propName;
+ }
+ let matcher = new ArgumentMatchers();
+ if (matcher.matcheStubKey(key)) {
+ key = matcher.matcheStubKey(key);
+ if (key) {
+ this.currentSetKey.set(f, key);
+ }
+ }
+ values.set(key, returnInfo);
+ this.stubs.set(f, values);
+ }
+
+ getReturnInfo(f, params) {
+ let values = this.stubs.get(f);
+ if (!values) {
+ return undefined;
+ }
+ let retrunKet = params[0];
+ if (typeof retrunKet == "undefined") {
+ retrunKet = "anonymous-mock-" + f.propName;
+ }
+ let stubSetKey = this.currentSetKey.get(f);
+
+ if (stubSetKey && (typeof (retrunKet) != "undefined")) {
+ retrunKet = stubSetKey;
+ }
+ let matcher = new ArgumentMatchers();
+ if (matcher.matcheReturnKey(params[0], undefined, stubSetKey) && matcher.matcheReturnKey(params[0], undefined, stubSetKey) != stubSetKey) {
+ retrunKet = params[0];
+ }
+
+ values.forEach(function (value, key, map) {
+ if (ArgumentMatchers.isRegExp(key) && matcher.matcheReturnKey(params[0], key)) {
+ retrunKet = key;
+ }
+ });
+
+ return values.get(retrunKet);
+ }
+
+ findName(obj, value) {
+ let properties = this.findProperties(obj);
+ let name = null;
+ properties.filter(item => (item !== 'caller' && item !== 'arguments')).forEach(
+ function (va1, idx, array) {
+ if (obj[va1] === value) {
+ name = va1;
+ }
+ }
+ );
+ return name;
+ }
+
+ isFunctionFromPrototype(f, container, propName) {
+ if (container.constructor != Object && container.constructor.prototype !== container) {
+ return container.constructor.prototype[propName] === f;
+ }
+ return false;
+ }
+
+ findProperties(obj, ...arg) {
+ function getProperty(new_obj) {
+ if (new_obj.__proto__ === null) {
+ return [];
+ }
+ let properties = Object.getOwnPropertyNames(new_obj);
+ return [...properties, ...getProperty(new_obj.__proto__)];
+ }
+ return getProperty(obj);
+ }
+
+ recordMethodCall(originalMethod, args) {
+ Function.prototype.getName = function () {
+ return this.name || this.toString().match(/function\s*([^(]*)\(/)[1];
+ };
+ let name = originalMethod.getName();
+ let arglistString = name + '(' + Array.from(args).toString() + ')';
+ let records = this.recordCalls.get(arglistString);
+ if (!records) {
+ records = 0;
+ }
+ records++;
+ this.recordCalls.set(arglistString, records);
+ }
+
+ mockFunc(originalObject, originalMethod) {
+ let tmp = this;
+ this.originalMethod = originalMethod;
+ let f = function () {
+ let args = arguments;
+ let action = tmp.getReturnInfo(f, args);
+ if (originalMethod) {
+ tmp.recordMethodCall(originalMethod, args);
+ }
+ if (action) {
+ return action.apply(this, args);
+ }
+ };
+
+ f.container = null || originalObject;
+ f.original = originalMethod || null;
+
+ if (originalObject && originalMethod) {
+ if (typeof (originalMethod) != 'function') throw new Error('Not a function');
+ var name = this.findName(originalObject, originalMethod);
+ originalObject[name] = f;
+ this.recordMockedMethod.set(name, originalMethod);
+ f.propName = name;
+ f.originalFromPrototype = this.isFunctionFromPrototype(f.original, originalObject, f.propName);
+ }
+ f.mocker = this;
+ this.mFunctions.push(f);
+ this.extend(f, new ExtendInterface(this));
+ return f;
+ }
+
+ verify(methodName, argsArray) {
+ if (!methodName) {
+ throw Error("not a function name");
+ }
+ let a = this.recordCalls.get(methodName + '(' + argsArray.toString() + ')');
+ return new VerificationMode(a ? a : 0);
+ }
+
+ mockObject(object) {
+ if (!object || typeof object === "string") {
+ throw Error(`this ${object} cannot be mocked`);
+ }
+ const _this = this;
+ let mockedObject = {};
+ let keys = Reflect.ownKeys(object);
+ keys.filter(key => (typeof Reflect.get(object, key)) === 'function')
+ .forEach(key => {
+ mockedObject[key] = object[key];
+ mockedObject[key] = _this.mockFunc(mockedObject, mockedObject[key]);
+ });
+ return mockedObject;
+ }
+}
+
+function ifMockedFunction(f) {
+ if (Object.prototype.toString.call(f) != "[object Function]" &&
+ Object.prototype.toString.call(f) != "[object AsyncFunction]") {
+ throw Error("not a function");
+ }
+ if (!f.stub) {
+ throw Error("not a mock function");
+ }
+ return true;
+}
+
+function when(f) {
+ if (ifMockedFunction(f)) {
+ return f.stub.bind(f);
+ }
+}
+
+export {MockKit, when};
\ No newline at end of file
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/mock/VerificationMode.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/mock/VerificationMode.js
new file mode 100644
index 0000000000000000000000000000000000000000..28eda2b05fa5ec9f78f9b20d1be1b6c87ffaf33b
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/mock/VerificationMode.js
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {expect} from '../../interface';
+
+class VerificationMode {
+ constructor(times) {
+ this.doTimes = times;
+ }
+
+ times(count) {
+ expect(count).assertEqual(this.doTimes);
+ }
+
+ never() {
+ console.log(this.doTimes);
+ expect(0).assertEqual(this.doTimes);
+ }
+
+ once() {
+ expect(1).assertEqual(this.doTimes);
+ }
+
+ atLeast(count) {
+ if (count > this.doTimes) {
+ throw Error('failed ' + count + ' greater than the actual execution times of method');
+ }
+ }
+
+ atMost(count) {
+ if (count < this.doTimes) {
+ throw Error('failed ' + count + ' less than the actual execution times of method');
+ }
+ }
+}
+
+export default VerificationMode;
\ No newline at end of file
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/report/OhReport.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/report/OhReport.js
new file mode 100644
index 0000000000000000000000000000000000000000..f648b11a9d0fd487cc0cc83b1ed360a788c5d700
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/report/OhReport.js
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import SysTestKit from "../kit/SysTestKit";
+import {collectCoverageData} from '../coverage/coverageCollect';
+import {TAG} from '../../Constant';
+
+class OhReport {
+ constructor(attr) {
+ this.delegator = attr.delegator;
+ this.abilityDelegatorArguments = attr.abilityDelegatorArguments;
+ this.id = 'report';
+ this.index = 0;
+ this.duration = 0;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ this.suiteService = this.coreContext.getDefaultService('suite');
+ this.specService = this.coreContext.getDefaultService('spec');
+ }
+
+ taskStart() {
+ }
+
+ async taskDone() {
+ if (this.abilityDelegatorArguments !== null) {
+ this.taskDoneTime = new Date().getTime();
+ let summary = this.suiteService.getSummary();
+ const configService = this.coreContext.getDefaultService('config');
+ if (configService['coverage'] === 'true') {
+ await collectCoverageData();
+ }
+ let message = '\n' + 'OHOS_REPORT_RESULT: stream=Tests run: ' + summary.total + ', Failure: ' + summary.failure;
+ message += ', Error: ' + summary.error;
+ message += ', Pass: ' + summary.pass;
+ message += ', Ignore: ' + summary.ignore;
+ message += '\n' + 'OHOS_REPORT_CODE: ' + (summary.failure > 0 ? -1 : 0) + '\n';
+ let isHasError = summary.failure > 0 || summary.error > 0;
+ let config = this.coreContext.getDefaultService('config');
+ if (config.isBreakOnError() && isHasError) {
+ // 未执行全部说明
+ message += '\n' + 'OHOS_REPORT_RESULT: breakOnError model, Stopping whole test suite if one specific test case failed or error' + '\n';
+ }
+ message += 'OHOS_REPORT_STATUS: taskconsuming=' + summary.duration + '\n';
+ console.info(`${message}`);
+ await SysTestKit.print(message);
+ }
+ console.info(`${TAG}report print success`);
+ this.delegator.finishTest('your test finished!!!', 0, () => { });
+ }
+
+ incorrectFormat() {
+ if (this.coreContext.getDefaultService('config').filterValid.length !== 0) {
+ var value = this.coreContext.getDefaultService('config').filterValid;
+ var message = 'this param ' + value.join(',') + ' is invalid' + '\n';
+ this.delegator.finishTest(message, 0, () => {
+ });
+ }
+ }
+
+ async suiteStart() {
+ if (this.abilityDelegatorArguments !== null) {
+ let message = '\n' + 'OHOS_REPORT_SUM: ' + this.suiteService.getCurrentRunningSuite().getSpecsNum();
+ message += '\n' + 'OHOS_REPORT_STATUS: class=' + this.suiteService.getCurrentRunningSuite().description + '\n';
+ console.info(`${message}`);
+ await SysTestKit.print(message);
+ console.info(`${TAG}${this.suiteService.getCurrentRunningSuite().description} suiteStart print success`);
+ }
+ }
+
+ async suiteDone() {
+ if (this.abilityDelegatorArguments !== null) {
+ const currentRunningSuite = this.suiteService.getCurrentRunningSuite();
+ let message = '\n' + 'OHOS_REPORT_STATUS: class=' + this.suiteService.getCurrentRunningSuite().description;
+ message += '\n' + 'OHOS_REPORT_STATUS: suiteconsuming=' + this.suiteService.getCurrentRunningSuite().duration;
+ if (currentRunningSuite.hookError) {
+ message += '\n' + `OHOS_REPORT_STATUS: ${currentRunningSuite.hookError.message}`;
+ }
+ message += '\n';
+ console.info(`${message}`);
+ await SysTestKit.print(message);
+ console.info(`${TAG}${this.suiteService.getCurrentRunningSuite().description} suiteDone print success`);
+ }
+ }
+
+ async specStart() {
+ if (this.abilityDelegatorArguments !== null) {
+ let message = '\n' + 'OHOS_REPORT_STATUS: class=' + this.suiteService.getCurrentRunningSuite().description;
+ message += '\n' + 'OHOS_REPORT_STATUS: current=' + (++this.index);
+ message += '\n' + 'OHOS_REPORT_STATUS: id=JS';
+ message += '\n' + 'OHOS_REPORT_STATUS: numtests=' + this.specService.getTestTotal();
+ message += '\n' + 'OHOS_REPORT_STATUS: stream=';
+ message += '\n' + 'OHOS_REPORT_STATUS: test=' + this.specService.currentRunningSpec.description;
+ message += '\n' + 'OHOS_REPORT_STATUS_CODE: 1' + '\n';
+ console.info(`${message}`);
+ await SysTestKit.print(message);
+ console.info(`${TAG}${this.specService.currentRunningSpec.description} specStart start print success`);
+ }
+ }
+
+ async specDone() {
+ if (this.abilityDelegatorArguments !== null) {
+ let message = '\n' + 'OHOS_REPORT_STATUS: class=' + this.suiteService.getCurrentRunningSuite().description;
+ message += '\n' + 'OHOS_REPORT_STATUS: current=' + (this.index);
+ message += '\n' + 'OHOS_REPORT_STATUS: id=JS';
+ message += '\n' + 'OHOS_REPORT_STATUS: numtests=' + this.specService.getTestTotal();
+ let errorMsg = '';
+ if (this.specService.currentRunningSpec.error) {
+ message += '\n' + 'OHOS_REPORT_STATUS: stack=' + this.specService.currentRunningSpec.error.message;
+ message += '\n' + 'OHOS_REPORT_STATUS: stream=';
+ message += '\n' + 'Error in ' + this.specService.currentRunningSpec.description;
+ message += '\n' + this.specService.currentRunningSpec.error.message;
+ message += '\n' + 'OHOS_REPORT_STATUS: test=' + this.specService.currentRunningSpec.description;
+ message += '\n' + 'OHOS_REPORT_STATUS_CODE: -1' + '\n';
+ } else if (this.specService.currentRunningSpec) {
+ if (this.specService.currentRunningSpec.fail) {
+ errorMsg = this.specService.currentRunningSpec.fail?.message;
+ message += '\n' + 'OHOS_REPORT_STATUS: stack=' + errorMsg;
+ message += '\n' + 'OHOS_REPORT_STATUS: stream=';
+ message += '\n' + 'Error in ' + this.specService.currentRunningSpec.description;
+ message += '\n' + errorMsg + '\n' + 'OHOS_REPORT_STATUS: test=' + this.specService.currentRunningSpec.description;
+ message += '\n' + 'OHOS_REPORT_STATUS_CODE: -2' + '\n';
+ } else {
+ message += '\n' + 'OHOS_REPORT_STATUS: stream=';
+ message += '\n' + 'OHOS_REPORT_STATUS: test=' + this.specService.currentRunningSpec.description;
+ message += '\n' + 'OHOS_REPORT_STATUS_CODE: 0' + '\n';
+ }
+ } else {
+ message += '\n';
+ }
+ message += 'OHOS_REPORT_STATUS: consuming=' + this.specService.currentRunningSpec.duration + '\n';
+ console.info(`${message}`);
+ await SysTestKit.print(message);
+ console.info(`${TAG}${this.specService.currentRunningSpec.description} specDone end print success`);
+ }
+ }
+}
+
+export default OhReport;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/report/ReportExtend.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/report/ReportExtend.js
new file mode 100644
index 0000000000000000000000000000000000000000..852fbcd5cbf97e776ebe5177a029df0f516594a5
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/module/report/ReportExtend.js
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class ReportExtend {
+ constructor(fileModule) {
+ this.id = 'extend';
+ this.fileModule = fileModule;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ this.suiteService = this.coreContext.getDefaultService('suite');
+ }
+
+ taskStart() {
+
+ }
+
+ taskDone() {
+ const report = {
+ tag: 'testsuites',
+ name: 'summary_report',
+ timestamp: new Date().toDateString(),
+ time: '1',
+ errors: 0,
+ failures: 0,
+ tests: 0,
+ children: []
+ };
+ const rootSuite = this.suiteService.rootSuite;
+ if (rootSuite && rootSuite.childSuites) {
+ for (let testsuite of rootSuite.childSuites) {
+ let suiteReport = {
+ tag: 'testsuite',
+ name: testsuite['description'],
+ errors: 0,
+ tests: 0,
+ failures: 0,
+ time: '0.1',
+ children: []
+ };
+ let specs = testsuite['specs'];
+ for (let testcase of specs) {
+ report.tests++;
+ suiteReport.tests++;
+ let caseReport = {
+ tag: 'testcase',
+ name: testcase['description'],
+ status: 'run',
+ time: '0.0',
+ classname: testsuite['description']
+ };
+ if (testcase.error) {
+ caseReport['result'] = false;
+ caseReport['children'] = [{
+ tag: 'error',
+ type: '',
+ message: testcase.error.message
+ }];
+ report.errors++;
+ suiteReport.errors++;
+ } else if (testcase.result.failExpects.length > 0) {
+ caseReport['result'] = false;
+ let message = '';
+ testcase.result.failExpects.forEach(failExpect => {
+ message += failExpect.message || ('expect ' + failExpect.actualValue + ' ' + failExpect.checkFunc + ' ' + (failExpect.expectValue || '')) + ';';
+ });
+ caseReport['children'] = [{
+ tag: 'failure',
+ type: '',
+ message: message
+ }];
+ report.failures++;
+ suiteReport.failures++;
+ } else {
+ caseReport['result'] = true;
+ }
+ suiteReport.children.push(caseReport);
+ }
+ report.children.push(suiteReport);
+ }
+ }
+
+ let reportXml = '\n' + json2xml(report);
+ this.fileModule.writeText({
+ uri: 'internal://app/report.xml',
+ text: reportXml,
+ success: function () {
+ console.info('call success callback success');
+ },
+ fail: function (data, code) {
+ console.info('call fail callback success:');
+ },
+ complete: function () {
+ console.info('call complete callback success');
+ }
+ });
+ }
+}
+
+function json2xml(json) {
+ let tagName;
+ let hasChildren = false;
+ let childrenStr = '';
+ let attrStr = '';
+ for (let key in json) {
+ if (key === 'tag') {
+ tagName = json[key];
+ } else if (key === 'children') {
+ if (json[key].length > 0) {
+ hasChildren = true;
+ for (let child of json[key]) {
+ childrenStr += json2xml(child);
+ }
+ }
+ } else {
+ attrStr += ` ${key}="${json[key]}"`;
+ }
+ }
+ let xml = `<${tagName}${attrStr}`;
+ xml += hasChildren ? `>${childrenStr}${tagName}>` : '/>';
+ return xml;
+}
+
+export default ReportExtend;
diff --git a/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/service.js b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/service.js
new file mode 100644
index 0000000000000000000000000000000000000000..55d04a8fc206b3ffe52f80e90e07c3fbf56be687
--- /dev/null
+++ b/oh_modules/.ohpm/@ohos+hypium@1.0.9/oh_modules/@ohos/hypium/src/main/service.js
@@ -0,0 +1,966 @@
+/*
+ * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import SysTestKit from "./module/kit/SysTestKit";
+import {TAG} from './Constant';
+
+class AssertException extends Error {
+ constructor(message) {
+ super();
+ this.name = "AssertException";
+ this.message = message;
+ }
+}
+
+function getFuncWithArgsZero(func, timeout, isStressTest) {
+ return new Promise(async (resolve, reject) => {
+ let timer = null;
+ if (!isStressTest) {
+ timer = setTimeout(() => {
+ reject(new Error('execute timeout ' + timeout + 'ms'));
+ }, timeout);
+ }
+ try {
+ await func();
+ } catch (err) {
+ reject(err);
+ }
+ timer !== null ? clearTimeout(timer) : null;
+ resolve();
+ });
+}
+
+function getFuncWithArgsOne(func, timeout, isStressTest) {
+ return new Promise(async (resolve, reject) => {
+ let timer = null;
+ if (!isStressTest) {
+ timer = setTimeout(() => {
+ reject(new Error('execute timeout ' + timeout + 'ms'));
+ }, timeout);;
+ }
+
+ function done() {
+ timer !== null ? clearTimeout(timer) : null;
+ resolve();
+ }
+
+ try {
+ await func(done);
+ } catch (err) {
+ timer !== null ? clearTimeout(timer) : null;
+ reject(err);
+ }
+ });
+}
+
+function getFuncWithArgsTwo(func, timeout, paramItem, isStressTest) {
+ return new Promise(async (resolve, reject) => {
+ let timer = null;
+ if (!isStressTest) {
+ timer = setTimeout(() => {
+ reject(new Error('execute timeout ' + timeout + 'ms'));
+ }, timeout);
+ }
+
+ function done() {
+ timer !== null ? clearTimeout(timer) : null;
+ resolve();
+ }
+
+ try {
+ await func(done, paramItem);
+ } catch (err) {
+ timer !== null ? clearTimeout(timer) : null;
+ reject(err);
+ }
+ });
+}
+
+function processFunc(coreContext, func) {
+ let argNames = ((func || '').toString()
+ .replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg, '')
+ .match(/^(function)?\s*[^\(]*\(\s*([^\)]*)\)/m) || ['', '', ''])[2]
+ .split(',') // split parameters
+ .map(item => item.replace(/^\s*(_?)(.+?)\1\s*$/, name => name.split('=')[0].trim()))
+ .filter(String);
+ let funcLen = func.length;
+ let processedFunc;
+ const config = coreContext.getDefaultService('config');
+ config.setSupportAsync(true);
+ const timeout = + (config.timeout === undefined ? 5000 : config.timeout);
+ const isStressTest = (coreContext.getServices('dataDriver') !== undefined || config.getStress() > 1);
+ switch (funcLen) {
+ case 0: {
+ processedFunc = function () {
+ return getFuncWithArgsZero(func, timeout, isStressTest);
+ };
+ break;
+ }
+ case 1: {
+ if (argNames[0] === 'data') {
+ processedFunc = function (paramItem) {
+ func(paramItem);
+ };
+ } else {
+ processedFunc = function () {
+ return getFuncWithArgsOne(func, timeout, isStressTest);
+ };
+ }
+ break;
+ }
+ default: {
+ processedFunc = function (paramItem) {
+ return getFuncWithArgsTwo(func, timeout, paramItem, isStressTest);
+ };
+ break;
+ }
+ }
+ return processedFunc;
+}
+
+function secureRandomNumber() {
+ return crypto.randomBytes(8).readUInt32LE() / 0xffffffff;
+}
+
+class SuiteService {
+ constructor(attr) {
+ this.id = attr.id;
+ this.rootSuite = new SuiteService.Suite({});
+ this.currentRunningSuite = this.rootSuite;
+ this.suitesStack = [this.rootSuite];
+ }
+
+ describe(desc, func) {
+ const configService = this.coreContext.getDefaultService('config');
+ if (configService.filterSuite(desc)) {
+ console.info(`${TAG}filter suite : ${desc}`);
+ return;
+ }
+ const suite = new SuiteService.Suite({description: desc});
+ if (typeof this.coreContext.getServices('dataDriver') !== 'undefined' && configService['dryRun'] !== 'true') {
+ let suiteStress = this.coreContext.getServices('dataDriver').dataDriver.getSuiteStress(desc);
+ for (let i = 1; i < suiteStress; i++) {
+ this.currentRunningSuite.childSuites.push(suite);
+ }
+ }
+ this.currentRunningSuite.childSuites.push(suite);
+ this.currentRunningSuite = suite;
+ this.suitesStack.push(suite);
+ func.call();
+ let childSuite = this.suitesStack.pop();
+ if (this.suitesStack.length === 0) {
+ this.currentRunningSuite = childSuite;
+ this.suitesStack.push(childSuite);
+ }
+ if (this.suitesStack.length > 1) {
+ this.currentRunningSuite = this.suitesStack.pop();
+ } else {
+ this.currentRunningSuite = this.suitesStack.pop();
+ this.suitesStack.push(this.currentRunningSuite);
+ }
+ }
+
+ beforeAll(func) {
+ this.currentRunningSuite.beforeAll.push(processFunc(this.coreContext, func));
+ }
+
+ beforeEach(func) {
+ this.currentRunningSuite.beforeEach.push(processFunc(this.coreContext, func));
+ }
+
+ afterAll(func) {
+ this.currentRunningSuite.afterAll.push(processFunc(this.coreContext, func));
+ }
+
+ afterEach(func) {
+ this.currentRunningSuite.afterEach.push(processFunc(this.coreContext, func));
+ }
+
+ getCurrentRunningSuite() {
+ return this.currentRunningSuite;
+ }
+
+ setCurrentRunningSuite(suite) {
+ this.currentRunningSuite = suite;
+ }
+
+ traversalResults(suite, obj, breakOnError) {
+ if (suite.childSuites.length === 0 && suite.specs.length === 0) {
+ return obj;
+ }
+ if (suite.specs.length > 0) {
+ for (const itItem of suite.specs) {
+ obj.total++;
+ if (breakOnError && (obj.error > 0 || obj.failure > 0)) { // breakOnError模式
+ continue;
+ }
+ if (itItem.error) {
+ obj.error++;
+ } else if (itItem.fail) {
+ obj.failure++;
+ } else if (itItem.pass === true) {
+ obj.pass++;
+ }
+ }
+ }
+
+ obj.duration += suite.duration;
+
+ if (suite.childSuites.length > 0) {
+ for (const suiteItem of suite.childSuites) {
+ this.traversalResults(suiteItem, obj, breakOnError);
+ }
+ }
+ }
+
+ async setSuiteResults(suite, error, coreContext) {
+ if (suite.childSuites.length === 0 && suite.specs.length === 0) {
+ return obj;
+ }
+ if (suite.specs.length > 0) {
+ const specService = coreContext.getDefaultService('spec');
+ for (const specItem of suite.specs) {
+ specService.setCurrentRunningSpec(specItem);
+ if (error instanceof AssertException) {
+ specItem.fail = error;
+ } else {
+ specItem.error = error;
+ }
+ await coreContext.fireEvents('spec', 'specStart', specItem);
+ await coreContext.fireEvents('spec', 'specDone', specItem);
+ }
+ }
+ if (suite.childSuites.length > 0) {
+ for (const suiteItem of suite.childSuites) {
+ await this.setSuiteResults(suiteItem, error, coreContext);
+ }
+ }
+ }
+
+ getSummary() {
+ let suiteService = this.coreContext.getDefaultService('suite');
+ let rootSuite = suiteService.rootSuite;
+ const specService = this.coreContext.getDefaultService('spec');
+ const configService = this.coreContext.getDefaultService('config');
+ let breakOnError = configService.isBreakOnError();
+ let isError = specService.getStatus();
+ let isBreaKOnError = breakOnError && isError;
+ let obj = {total: 0, failure: 0, error: 0, pass: 0, ignore: 0, duration: 0};
+ for (const suiteItem of rootSuite.childSuites) {
+ this.traversalResults(suiteItem, obj, isBreaKOnError);
+ }
+ obj.ignore = obj.total - obj.pass - obj.failure - obj.error;
+ return obj;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ }
+
+ traversalSuites(suite, obj, configService) {
+ if (suite.childSuites.length === 0 && suite.specs.length === 0) {
+ return [];
+ }
+ if (suite.specs.length > 0) {
+ let itArray = [];
+ for (const itItem of suite['specs']) {
+ if (!configService.filterDesc(suite.description, itItem.description, itItem.fi, null)) {
+ itArray.push({'itName': itItem.description});
+ }
+ }
+ obj[suite.description] = itArray;
+ }
+
+ if (suite.childSuites.length > 0) {
+ let suiteArray = [];
+ for (const suiteItem of suite.childSuites) {
+ let suiteObj = {};
+ this.traversalSuites(suiteItem, suiteObj, configService);
+ if (!configService.filterSuite(suiteItem.description)) {
+ suiteArray.push(suiteObj);
+ }
+ }
+ obj.suites = suiteArray;
+ }
+ }
+
+ async dryRun(abilityDelegator) {
+ const configService = this.coreContext.getDefaultService('config');
+ let testSuitesObj = {};
+ let suitesArray = [];
+ for (const suiteItem of this.rootSuite.childSuites) {
+ let obj = {};
+ this.traversalSuites(suiteItem, obj, configService);
+ if (!configService.filterSuite(suiteItem.description)) {
+ suitesArray.push(obj);
+ }
+ }
+ testSuitesObj['suites'] = suitesArray;
+
+ let strJson = JSON.stringify(testSuitesObj);
+ let strLen = strJson.length;
+ let maxLen = 500;
+ let maxCount = Math.floor(strLen / maxLen);
+
+ for (let count = 0; count <= maxCount; count++) {
+ await SysTestKit.print(strJson.substring(count * maxLen, (count + 1) * maxLen));
+ }
+ console.info(`${TAG}dryRun print success`);
+ abilityDelegator.finishTest('dry run finished!!!', 0, () => { });
+ }
+
+ execute() {
+ const configService = this.coreContext.getDefaultService('config');
+ if (configService.filterValid.length !== 0) {
+ this.coreContext.fireEvents('task', 'incorrectFormat');
+ return;
+ }
+
+ if (configService.isRandom() && this.rootSuite.childSuites.length > 0) {
+ this.rootSuite.childSuites.sort(function () {
+ return Math.random().toFixed(1) > 0.5 ? -1 : 1;
+ });
+ this.currentRunningSuite = this.rootSuite.childSuites[0];
+ }
+
+ if (configService.isSupportAsync()) {
+ let asyncExecute = async () => {
+ await this.coreContext.fireEvents('task', 'taskStart');
+ await this.rootSuite.asyncRun(this.coreContext);
+ };
+ asyncExecute().then(async () => {
+ await this.coreContext.fireEvents('task', 'taskDone');
+ });
+ } else {
+ this.coreContext.fireEvents('task', 'taskStart');
+ this.rootSuite.run(this.coreContext);
+ this.coreContext.fireEvents('task', 'taskDone');
+ }
+ }
+
+ apis() {
+ const _this = this;
+ return {
+ describe: function (desc, func) {
+ return _this.describe(desc, func);
+ },
+ beforeAll: function (func) {
+ return _this.beforeAll(func);
+ },
+ beforeEach: function (func) {
+ return _this.beforeEach(func);
+ },
+ afterAll: function (func) {
+ return _this.afterAll(func);
+ },
+ afterEach: function (func) {
+ return _this.afterEach(func);
+ }
+ };
+ }
+}
+
+SuiteService.Suite = class {
+ constructor(attrs) {
+ this.description = attrs.description || '';
+ this.childSuites = [];
+ this.specs = [];
+ this.beforeAll = [];
+ this.afterAll = [];
+ this.beforeEach = [];
+ this.afterEach = [];
+ this.duration = 0;
+ this.hookError = null;
+ }
+
+ pushSpec(spec) {
+ this.specs.push(spec);
+ }
+
+ removeSpec(desc) {
+ this.specs = this.specs.filter((item, index) => {
+ return item.description !== desc;
+ });
+ }
+
+ getSpecsNum() {
+ return this.specs.length;
+ }
+
+ isRun(coreContext) {
+ const configService = coreContext.getDefaultService('config');
+ const suiteService = coreContext.getDefaultService('suite');
+ const specService = coreContext.getDefaultService('spec');
+ let breakOnError = configService.isBreakOnError();
+ let isError = specService.getStatus();
+ return breakOnError && isError;
+ }
+
+ run(coreContext) {
+ const suiteService = coreContext.getDefaultService('suite');
+ suiteService.setCurrentRunningSuite(this);
+ if (this.description !== '') {
+ coreContext.fireEvents('suite', 'suiteStart', this);
+ }
+ this.runHookFunc('beforeAll');
+ if (this.specs.length > 0) {
+ const configService = coreContext.getDefaultService('config');
+ if (configService.isRandom()) {
+ this.specs.sort(function () {
+ return Math.random().toFixed(1) > 0.5 ? -1 : 1;
+ });
+ }
+ for (let spec in this.specs) {
+ let isBreakOnError = this.isRun(coreContext);
+ if (isBreakOnError) {
+ break;
+ }
+ this.runHookFunc('beforeEach');
+ spec.run(coreContext);
+ this.runHookFunc('afterEach');
+ }
+ }
+ if (this.childSuites.length > 0) {
+ for (let suite in this.childSuites) {
+ let isBreakOnError = this.isRun(coreContext);
+ if (isBreakOnError) {
+ break;
+ }
+ suite.run(coreContext);
+ suiteService.setCurrentRunningSuite(suite);
+ }
+ }
+ this.runHookFunc('afterAll');
+ if (this.description !== '') {
+ coreContext.fireEvents('suite', 'suiteDone');
+ }
+ }
+
+ async asyncRunSpecs(coreContext) {
+ const configService = coreContext.getDefaultService('config');
+ if (configService.isRandom()) {
+ this.specs.sort(function () {
+ return Math.random().toFixed(1) > 0.5 ? -1 : 1;
+ });
+ }
+ const specService = coreContext.getDefaultService('spec');
+ for (let specItem of this.specs) {
+ specService.setCurrentRunningSpec(specItem);
+ // 遇错即停模式,发现用例有问题,直接返回,不在执行后面的it
+ let isBreakOnError = this.isRun(coreContext);
+ if (isBreakOnError) {
+ console.log("break description :" + this.description);
+ break;
+ }
+ await coreContext.fireEvents('spec', 'specStart', specItem);
+ try {
+ await this.runAsyncHookFunc('beforeEach');
+ await specItem.asyncRun(coreContext);
+ await this.runAsyncHookFunc('afterEach');
+ } catch (e) {
+ console.error(`${TAG}${e?.stack}`);
+ if (e instanceof AssertException) {
+ specItem.fail = e;
+ } else {
+ specItem.error = e;
+ }
+ specService.setStatus(true);
+ }
+ specItem.setResult();
+ await coreContext.fireEvents('spec', 'specDone', specItem);
+ specService.setCurrentRunningSpec(null);
+ }
+ }
+
+ async asyncRunChildSuites(coreContext) {
+ for (let i = 0; i < this.childSuites.length; i++) {
+ // 遇错即停模式, 发现用例有问题,直接返回,不在执行后面的description
+ let isBreakOnError = this.isRun(coreContext);
+ if (isBreakOnError) {
+ console.log(`${TAG}break description : ${this.description}`);
+ break;
+ }
+ await this.childSuites[i].asyncRun(coreContext);
+ }
+ }
+
+ async asyncRun(coreContext) {
+ const suiteService = coreContext.getDefaultService('suite');
+ const specService = coreContext.getDefaultService('spec');
+
+ suiteService.setCurrentRunningSuite(this);
+ suiteService.suitesStack.push(this);
+ if (this.description !== '') {
+ await coreContext.fireEvents('suite', 'suiteStart', this);
+ }
+
+ try {
+ await this.runAsyncHookFunc('beforeAll');
+ } catch (error) {
+ console.error(`${TAG}${error?.stack}`);
+ this.hookError = error;
+ }
+
+ if (this.hookError !== null) {
+ specService.setStatus(true);
+ await suiteService.setSuiteResults(this, this.hookError, coreContext);
+ }
+
+ if (this.specs.length > 0 && this.hookError === null) {
+ await this.asyncRunSpecs(coreContext);
+ }
+
+ if (this.childSuites.length > 0 && this.hookError === null) {
+ await this.asyncRunChildSuites(coreContext);
+ }
+
+ try {
+ await this.runAsyncHookFunc('afterAll');
+ } catch (error) {
+ console.error(`${TAG}${error?.stack}`);
+ this.hookError = error;
+ specService.setStatus(true);
+ }
+
+ if (this.description !== '') {
+ await coreContext.fireEvents('suite', 'suiteDone');
+ let childSuite = suiteService.suitesStack.pop();
+ if (suiteService.suitesStack.length === 0) {
+ suiteService.suitesStack.push(childSuite);
+ }
+ if (suiteService.suitesStack.length > 1) {
+ suiteService.setCurrentRunningSuite(suiteService.suitesStack.pop());
+ } else {
+ let currentRunningSuite = suiteService.suitesStack.pop();
+ suiteService.setCurrentRunningSuite(currentRunningSuite);
+ suiteService.suitesStack.push(currentRunningSuite);
+ }
+ }
+ }
+
+ runHookFunc(hookName) {
+ if (this[hookName] && this[hookName].length > 0) {
+ this[hookName].forEach(func => {
+ try {
+ func();
+ } catch (e) {
+ console.error(`${TAG}${e.stack}`);
+ }
+ });
+ }
+ }
+
+ async runAsyncHookFunc(hookName) {
+ for (const hookItem of this[hookName]) {
+ try {
+ await hookItem();
+ } catch (error) {
+ error['message'] += `, error in ${hookName} function`;
+ throw error;
+ }
+
+ }
+ }
+};
+
+class SpecService {
+ constructor(attr) {
+ this.id = attr.id;
+ this.totalTest = 0;
+ this.hasError = false;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ }
+
+ setCurrentRunningSpec(spec) {
+ this.currentRunningSpec = spec;
+ }
+
+ setStatus(obj) {
+ this.hasError = obj;
+ }
+
+ getStatus() {
+ return this.hasError;
+ }
+
+ getTestTotal() {
+ return this.totalTest;
+ }
+
+ getCurrentRunningSpec() {
+ return this.currentRunningSpec;
+ }
+
+ it(desc, filter, func) {
+ const configService = this.coreContext.getDefaultService('config');
+ const currentSuiteName = this.coreContext.getDefaultService('suite').getCurrentRunningSuite().description;
+ if (configService.filterDesc(currentSuiteName, desc, filter, this.coreContext)) {
+ console.info(`${TAG}filter it :${desc}`);
+ } else {
+ let processedFunc = processFunc(this.coreContext, func);
+ const spec = new SpecService.Spec({description: desc, fi: filter, fn: processedFunc});
+ const suiteService = this.coreContext.getDefaultService('suite');
+ if (typeof this.coreContext.getServices('dataDriver') !== 'undefined' && configService['dryRun'] !== 'true') {
+ let specStress = this.coreContext.getServices('dataDriver').dataDriver.getSpecStress(desc);
+ for (let i = 1; i < specStress; i++) {
+ this.totalTest++;
+ suiteService.getCurrentRunningSuite().pushSpec(spec);
+ }
+ }
+
+ // dryRun 状态下不统计压力测试重复数据
+ if (configService['dryRun'] !== 'true') {
+ let stress = configService.getStress(); // 命令配置压力测试
+ console.info(`${TAG}stress length : ${stress}`);
+ for (let i = 1; i < stress; i++) {
+ this.totalTest++;
+ suiteService.getCurrentRunningSuite().pushSpec(spec);
+ }
+ }
+ this.totalTest++;
+ suiteService.getCurrentRunningSuite().pushSpec(spec);
+ }
+ }
+
+ apis() {
+ const _this = this;
+ return {
+ it: function (desc, filter, func) {
+ return _this.it(desc, filter, func);
+ }
+ };
+ }
+}
+
+SpecService.Spec = class {
+ constructor(attrs) {
+ this.description = attrs.description || '';
+ this.fi = attrs.fi;
+ this.fn = attrs.fn || function () {
+ };
+ this.fail = undefined;
+ this.error = undefined;
+ this.duration = 0;
+ this.startTime = 0;
+ this.isExecuted = false; // 当前用例是否执行
+ }
+
+ setResult() {
+ if (this.fail) {
+ this.pass = false;
+ } else {
+ this.pass = true;
+ }
+ }
+
+ run(coreContext) {
+ const specService = coreContext.getDefaultService('spec');
+ specService.setCurrentRunningSpec(this);
+ coreContext.fireEvents('spec', 'specStart', this);
+ this.isExecuted = true;
+ try {
+ let dataDriver = coreContext.getServices('dataDriver');
+ if (typeof dataDriver === 'undefined') {
+ this.fn();
+ } else {
+ let suiteParams = dataDriver.dataDriver.getSuiteParams();
+ let specParams = dataDriver.dataDriver.getSpecParams();
+ console.info(`${TAG}[suite params] ${JSON.stringify(suiteParams)}`);
+ console.info(`${TAG}[spec params] ${JSON.stringify(specParams)}`);
+ if (this.fn.length === 0) {
+ this.fn();
+ } else if (specParams.length === 0) {
+ this.fn(suiteParams);
+ } else {
+ specParams.forEach(paramItem => this.fn(Object.assign({}, paramItem, suiteParams)));
+ }
+ }
+ this.setResult();
+ } catch (e) {
+ this.error = e;
+ specService.setStatus(true);
+ }
+ coreContext.fireEvents('spec', 'specDone', this);
+ }
+
+ async asyncRun(coreContext) {
+ const dataDriver = coreContext.getServices('dataDriver');
+ if (typeof dataDriver === 'undefined') {
+ await this.fn();
+ } else {
+ const suiteParams = dataDriver.dataDriver.getSuiteParams();
+ const specParams = dataDriver.dataDriver.getSpecParams();
+ console.info(`[suite params] ${JSON.stringify(suiteParams)}`);
+ console.info(`[spec params] ${JSON.stringify(specParams)}`);
+ if (this.fn.length === 0) {
+ await this.fn();
+ } else if (specParams.length === 0) {
+ await this.fn(suiteParams);
+ } else {
+ for (const paramItem of specParams) {
+ await this.fn(Object.assign({}, paramItem, suiteParams));
+ }
+ }
+ }
+
+ this.isExecuted = true;
+ }
+
+ filterCheck(coreContext) {
+ const specService = coreContext.getDefaultService('spec');
+ specService.setCurrentRunningSpec(this);
+ return true;
+ }
+};
+
+class ExpectService {
+ constructor(attr) {
+ this.id = attr.id;
+ this.matchers = {};
+ }
+
+ expect(actualValue) {
+ return this.wrapMatchers(actualValue);
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ this.addMatchers(this.basicMatchers());
+ }
+
+ addMatchers(matchers) {
+ for (const matcherName in matchers) {
+ if (Object.prototype.hasOwnProperty.call(matchers, matcherName)) {
+ this.matchers[matcherName] = matchers[matcherName];
+ }
+ }
+ }
+
+ basicMatchers() {
+ return {
+ assertTrue: function (actualValue) {
+ return {
+ pass: (actualValue) === true,
+ message: 'expect true, actualValue is ' + actualValue
+ };
+ },
+ assertEqual: function (actualValue, args) {
+ return {
+ pass: (actualValue) === args[0],
+ expectValue: args[0],
+ message: 'expect ' + actualValue + ' equals ' + args[0]
+ };
+ },
+ assertThrow: function (actual, args) {
+ const result = {
+ pass: false
+ };
+ if (typeof actual !== 'function') {
+ result.message = 'toThrow\'s Actual should be a Function';
+ } else {
+ let hasThrow = false;
+ let throwError;
+ try {
+ actual();
+ } catch (e) {
+ hasThrow = true;
+ throwError = e;
+ }
+ if (!hasThrow) {
+ result.message = 'function did not throw an exception';
+ } else if (throwError && throwError.message === args[0]) {
+ result.pass = true;
+ } else {
+ result.message = `expect to throw ${args[0]} , actual throw ${throwError.message}`;
+ }
+ }
+ return result;
+ }
+ };
+ }
+
+ wrapMatchers(actualValue) {
+ const _this = this;
+ const wrappedMatchers = {
+ // 翻转标识
+ isNot: false,
+
+ // 翻转方法
+ not: function () {
+ this.isNot = true;
+ return this;
+ }
+ };
+ const specService = _this.coreContext.getDefaultService('spec');
+ const currentRunningSpec = specService.getCurrentRunningSpec();
+ const currentRunningSuite = _this.coreContext.getDefaultService('suite').getCurrentRunningSuite();
+ for (const matcherName in this.matchers) {
+ let result = Object.prototype.hasOwnProperty.call(this.matchers, matcherName);
+ if (!result) {
+ continue;
+ }
+ if (matcherName.search('assertPromise') == 0) {
+ wrappedMatchers[matcherName] = async function () {
+ await _this.matchers[matcherName](actualValue, arguments).then(function (result) {
+ if (wrappedMatchers.isNot) {
+ result.pass = !result.pass;
+ }
+ result.actualValue = actualValue;
+ result.checkFunc = matcherName;
+ if (!result.pass) {
+ const assertError = new AssertException(result.message);
+ currentRunningSpec ? currentRunningSpec.fail = assertError : currentRunningSuite.hookError = assertError;
+ throw assertError;
+ }
+ });
+ };
+ } else {
+ wrappedMatchers[matcherName] = function () {
+ const result = _this.matchers[matcherName](actualValue, arguments);
+ if (wrappedMatchers.isNot) {
+ result.pass = !result.pass;
+ }
+ result.actualValue = actualValue;
+ result.checkFunc = matcherName;
+ if (!result.pass) {
+ const assertError = new AssertException(result.message);
+ currentRunningSpec ? currentRunningSpec.fail = assertError : currentRunningSuite.hookError = assertError;
+ throw assertError;
+ }
+ };
+ }
+ }
+ return wrappedMatchers;
+ }
+
+ apis() {
+ const _this = this;
+ return {
+ expect: function (actualValue) {
+ return _this.expect(actualValue);
+ }
+ };
+ }
+}
+
+class ReportService {
+ constructor(attr) {
+ this.id = attr.id;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ this.specService = this.coreContext.getDefaultService('spec');
+ this.suiteService = this.coreContext.getDefaultService('suite');
+ this.duration = 0;
+ }
+
+ taskStart() {
+ console.info(`${TAG}[start] start run suites`);
+ }
+
+ async suiteStart() {
+ console.info(`${TAG}[suite start]${this.suiteService.getCurrentRunningSuite().description}`);
+ }
+
+ async specStart() {
+ console.info(`${TAG}start running case '${this.specService.currentRunningSpec.description}'`);
+ this.index = this.index + 1;
+ let spec = this.specService.currentRunningSpec;
+ spec.startTime = await SysTestKit.getRealTime();
+ }
+
+ async specDone() {
+ let msg = '';
+ let spec = this.specService.currentRunningSpec;
+ let suite = this.suiteService.currentRunningSuite;
+ spec.duration = await SysTestKit.getRealTime() - spec.startTime;
+ suite.duration += spec.duration;
+ if (spec.error) {
+ this.formatPrint('error', spec.description + ' ; consuming ' + spec.duration + 'ms');
+ this.formatPrint('errorDetail', spec.error);
+ } else if (spec.fail) {
+ this.formatPrint('fail', spec.description + ' ; consuming ' + spec.duration + 'ms');
+ this.formatPrint('failDetail', spec.fail?.message);
+ } else {
+ this.formatPrint('pass', spec.description + ' ; consuming ' + spec.duration + 'ms');
+ }
+ this.formatPrint(this.specService.currentRunningSpec.error, msg);
+ }
+
+ suiteDone() {
+ let suite = this.suiteService.currentRunningSuite;
+ let message = suite.hookError ? `, ${suite.hookError?.message}` : '';
+ console.info(`[suite end] ${suite.description} consuming ${suite.duration} ms${message}`);
+ }
+
+ taskDone() {
+ let msg = '';
+ let summary = this.suiteService.getSummary();
+ msg = 'total cases:' + summary.total + ';failure ' + summary.failure + ',' + 'error ' + summary.error;
+ msg += ',pass ' + summary.pass + '; consuming ' + summary.duration + 'ms';
+ console.info(`${TAG}${msg}`);
+ console.info(`${TAG}[end] run suites end`);
+ }
+
+ incorrectFormat() {
+ if (this.coreContext.getDefaultService('config').filterValid.length !== 0) {
+ this.coreContext.getDefaultService('config').filterValid.forEach(function (item) {
+ console.info(`${TAG}this param ${item} is invalid`);
+ });
+ }
+ }
+
+ formatPrint(type, msg) {
+ switch (type) {
+ case 'pass':
+ console.info(`${TAG}[pass]${msg}`);
+ break;
+ case 'fail':
+ console.info(`${TAG}[fail]${msg}`);
+ break;
+ case 'failDetail':
+ console.info(`${TAG}[failDetail]${msg}`);
+ break;
+ case 'error':
+ console.info(`${TAG}[error]${msg}`);
+ break;
+ case 'errorDetail':
+ console.info(`${TAG}[errorDetail]${msg}`);
+ break;
+ }
+ }
+
+ sleep(numberMillis) {
+ var now = new Date();
+ var exitTime = now.getTime() + numberMillis;
+ while (true) {
+ now = new Date();
+ if (now.getTime() > exitTime) {
+ return;
+ }
+ }
+ }
+}
+
+export {
+ SuiteService,
+ SpecService,
+ ExpectService,
+ ReportService
+};
diff --git a/oh_modules/.ohpm/lock.json5 b/oh_modules/.ohpm/lock.json5
new file mode 100644
index 0000000000000000000000000000000000000000..199489bcfa9cd04ed6c14cf15be427a39912a337
--- /dev/null
+++ b/oh_modules/.ohpm/lock.json5
@@ -0,0 +1,102 @@
+{
+ "lockVersion": "1.0",
+ "settings": {
+ "resolveConflict": true,
+ "resolveConflictStrict": false,
+ "installAll": true
+ },
+ "overrides": {},
+ "overrideDependencyMap": {},
+ "modules": {
+ ".": {
+ "name": "",
+ "dependencies": {
+ "@ohos/hypium": {
+ "specifier": "1.0.9",
+ "version": "1.0.9"
+ }
+ },
+ "devDependencies": {},
+ "dynamicDependencies": {},
+ "maskedByOverrideDependencyMap": false
+ },
+ "common": {
+ "name": "common",
+ "dependencies": {},
+ "devDependencies": {},
+ "dynamicDependencies": {},
+ "maskedByOverrideDependencyMap": false
+ },
+ "feature/recorder": {
+ "name": "recorder",
+ "dependencies": {},
+ "devDependencies": {
+ "@ohos/common": {
+ "specifier": "file:common",
+ "version": "file:common"
+ }
+ },
+ "dynamicDependencies": {},
+ "maskedByOverrideDependencyMap": false
+ },
+ "product/phone": {
+ "name": "phone",
+ "dependencies": {
+ "@ohos/recorder": {
+ "specifier": "file:feature/recorder",
+ "version": "file:feature/recorder"
+ },
+ "@ohos/common": {
+ "specifier": "file:common",
+ "version": "file:common"
+ }
+ },
+ "devDependencies": {},
+ "dynamicDependencies": {},
+ "maskedByOverrideDependencyMap": false
+ },
+ "product/tablet": {
+ "name": "tablet",
+ "dependencies": {
+ "@ohos/recorder": {
+ "specifier": "file:feature/recorder",
+ "version": "file:feature/recorder"
+ },
+ "@ohos/common": {
+ "specifier": "file:common",
+ "version": "file:common"
+ }
+ },
+ "devDependencies": {},
+ "dynamicDependencies": {},
+ "maskedByOverrideDependencyMap": false
+ }
+ },
+ "packages": {
+ "@ohos/hypium@1.0.9": {
+ "integrity": "sha512-qW5HE293s8+YRwh+6reJjR1Q08iuhay2RdPJ/JJWOI9/mjHn/zMW4i/CUfhvqlAD2w+PXUfwAYoXItc4OQpo6A==",
+ "storePath": "oh_modules/.ohpm/@ohos+hypium@1.0.9",
+ "dependencies": {},
+ "dynamicDependencies": {},
+ "dev": false,
+ "dynamic": false,
+ "maskedByOverrideDependencyMap": false
+ },
+ "@ohos/common@file:common": {
+ "storePath": "common",
+ "dependencies": {},
+ "dynamicDependencies": {},
+ "dev": true,
+ "dynamic": false,
+ "maskedByOverrideDependencyMap": false
+ },
+ "@ohos/recorder@file:feature/recorder": {
+ "storePath": "feature/recorder",
+ "dependencies": {},
+ "dynamicDependencies": {},
+ "dev": false,
+ "dynamic": false,
+ "maskedByOverrideDependencyMap": false
+ }
+ }
+}
\ No newline at end of file
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/CHANGELOG.md b/oh_modules/.ohpm/oh_modules/@ohos/hypium/CHANGELOG.md
new file mode 100644
index 0000000000000000000000000000000000000000..79c11d2bdeba38bc18f0f3bdf4723e4f1d77263b
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/CHANGELOG.md
@@ -0,0 +1,50 @@
+## 1.0.9
+
+- 测试hook方法支持断言与异常
+- 修复不能mock静态方法的问题
+
+## 1.0.6
+
+- 适配模块化编译
+- 适配IDE覆盖率数据输出
+
+## 1.0.5
+
+- 优化接口异常场景处理能力
+- 修复大规模压力测试下内存溢出问题
+- 修复测试脚本定义扩展原型方法与框架的兼容性问题
+- 异步promise状态判断断言与取反断言兼容
+
+## 1.0.4
+
+- 新增异步promise状态判断断言
+- 新增基础数据判断断言
+- 新增断言异常信息描述
+- 优化用例计时逻辑,采用相对时间计时
+- 修改用例执行过程,异步执行
+- 修复用例结果偶现的乱序问题
+
+## 1.0.3
+
+- 新增mock对象的能力,支持mock无参数函数
+- 新增测试套、测试用例随机执行功能
+- 解决测试套声明不规范,导致用例加载异常的问题
+- 修复命令行窗口输出乱序的问题
+
+## 1.0.2
+
+- 新增mock接口,判断当前mock方法状态、使用次数
+- 修复用例耗时统计问题
+- 修改断言功能,断言失败后,会抛出异常
+
+## 1.0.1
+- 新增mock基础能力
+- 修复部分断言失败后,消息提示异常问题
+
+## 1.0.0
+- 新增应用日志关键字查询接口,查询hilog日志中是否包含指定字符串
+- 支持用例筛选功能,用于指定测试用例的执行。可按用例名称、类型、规模、级别与测试套名称筛选
+- 支持新SDK下单元测试
+- 支持dry run 功能,通过命令行传参数,返回当前测试套用例名称全集
+- 新增框架接口声明文件,用于deveco联想
+- 修复用例状态统计问题
\ No newline at end of file
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/LICENSE b/oh_modules/.ohpm/oh_modules/@ohos/hypium/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..4947287f7b5ccb5d1e8b7b2d3aa5d89f322c160d
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
\ No newline at end of file
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/README.md b/oh_modules/.ohpm/oh_modules/@ohos/hypium/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..83ddccc702c7b280100436d0a428bae203eb7f4b
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/README.md
@@ -0,0 +1,219 @@
+
Hypium
+
A unit test framework for OpenHarmonyOS application
+
+## Hypium是什么?
+***
+- Hypium是OpenHarmony上的测试框架,提供测试用例编写、执行、结果显示能力,用于OpenHarmony系统应用接口以及应用界面测试。
+- Hypium结构化模型:hypium工程主要由List.test.js与TestCase.test.js组成。
+```
+rootProject // Hypium工程根目录
+├── moduleA
+│ ├── src
+│ ├── main // 被测试应用目录
+│ ├── ohosTest // 测试用例目录
+│ ├── js/ets
+│ └── test
+│ └── List.test.js // 测试用例加载脚本,ets目录下为.ets后缀
+│ └── TestCase.test.js // 测试用例脚本,ets目录下为.ets后缀
+└── moduleB
+ ...
+│ └── List.test.js // 测试用例加载脚本,ets目录下为.ets后缀
+│ └── TestCase.test.js // 测试用例脚本,ets目录下为.ets后缀
+```
+
+## 安装使用
+***
+- 在DevEco Studio内使用Hypium
+- 工程级package.json内配置:
+```json
+"dependencies": {
+ "@ohos/hypium": "1.0.9"
+}
+```
+注:
+hypium服务于OpenHarmonyOS应用对外接口测试、系统对外接口测试(SDK中接口),完成HAP自动化测试。详细指导:
+[Deveco Studio](https://developer.harmonyos.com/cn/develop/deveco-studio)
+
+#### 通用语法
+
+- 测试用例采用业内通用语法,describe代表一个测试套, it代表一条用例。
+
+| No. | API | 功能说明 |
+| --- | ---------- | ---------------------------------------------------------------------------------------------------------------------- |
+| 1 | describe | 定义一个测试套,支持两个参数:测试套名称和测试套函数 |
+| 2 | beforeAll | 在测试套内定义一个预置条件,在所有测试用例开始前执行且仅执行一次,支持一个参数:预置动作函数 |
+| 3 | beforeEach | 在测试套内定义一个单元预置条件,在每条测试用例开始前执行,执行次数与it定义的测试用例数一致,支持一个参数:预置动作函数 |
+| 4 | afterEach | 在测试套内定义一个单元清理条件,在每条测试用例结束后执行,执行次数与it定义的测试用例数一致,支持一个参数:清理动作函数 |
+| 5 | afterAll | 在测试套内定义一个清理条件,在所有测试用例结束后执行且仅执行一次,支持一个参数:清理动作函数 |
+| 6 | it | 定义一条测试用例,支持三个参数:用例名称,过滤参数和用例函数 |
+| 7 | expect | 支持bool类型判断等多种断言方法 |
+
+#### 断言库
+
+- 示例代码:
+
+```javascript
+ expect(${actualvalue}).assertX(${expectvalue})
+```
+
+- 断言功能列表:
+
+| No. | API | 功能说明 |
+| :--- | :------------------------------- | ---------------------------------------------------------------------------------------------- |
+| 1 | assertClose | 检验actualvalue和expectvalue(0)的接近程度是否是expectValue(1) |
+| 2 | assertContain | 检验actualvalue中是否包含expectvalue |
+| 3 | assertDeepEquals | @since1.0.4 检验actualvalue和expectvalue(0)是否是同一个对象 |
+| 4 | assertEqual | 检验actualvalue是否等于expectvalue[0] |
+| 5 | assertFail | 抛出一个错误 |
+| 6 | assertFalse | 检验actualvalue是否是false |
+| 7 | assertTrue | 检验actualvalue是否是true |
+| 8 | assertInstanceOf | 检验actualvalue是否是expectvalue类型 |
+| 9 | assertLarger | 检验actualvalue是否大于expectvalue |
+| 10 | assertLess | 检验actualvalue是否小于expectvalue |
+| 11 | assertNaN | @since1.0.4 检验actualvalue是否是NaN |
+| 12 | assertNegUnlimited | @since1.0.4 检验actualvalue是否等于Number.NEGATIVE_INFINITY |
+| 13 | assertNull | 检验actualvalue是否是null |
+| 14 | assertPosUnlimited | @since1.0.4 检验actualvalue是否等于Number.POSITIVE_INFINITY |
+| 15 | assertPromiseIsPending | @since1.0.4 检验actualvalue是否处于Pending状态【actualvalue为promse对象】 |
+| 16 | assertPromiseIsRejected | @since1.0.4 检验actualvalue是否处于Rejected状态【同15】 |
+| 17 | assertPromiseIsRejectedWith | @since1.0.4 检验actualvalue是否处于Rejected状态,并且比较执行的结果值【同15】 |
+| 18 | assertPromiseIsRejectedWithError | @since1.0.4 检验actualvalue是否处于Rejected状态并有异常,同时比较异常的类型和message值【同15】 |
+| 19 | assertPromiseIsResolved | @since1.0.4 检验actualvalue是否处于Resolved状态【同15】 |
+| 20 | assertPromiseIsResolvedWith | @since1.0.4 检验actualvalue是否处于Resolved状态,并且比较执行的结果值【同15】 |
+| 21 | assertThrowError | 检验actualvalue抛出Error内容是否是expectValue |
+| 22 | assertUndefined | 检验actualvalue是否是undefined |
+| 23 | not | @since1.0.4 断言结果取反 |
+
+
+ 示例代码:
+
+```javascript
+ import { describe, it, expect } from '@ohos/hypium';
+
+ export default async function assertCloseTest() {
+ describe('assertClose', function () {
+ it('assertClose_success', 0, function () {
+ let a = 100;
+ let b = 0.1;
+ expect(a).assertClose(99, b);
+ })
+ })
+ }
+```
+
+#### 公共系统能力
+
+| No. | API | 功能描述 |
+| ---- | ------------------------------------------------------- | ------------------------------------------------------------ |
+| 1 | existKeyword(keyword: string, timeout: number): boolean | @since1.0.3 hilog日志中查找指定字段是否存在,keyword是待查找关键字,timeout为设置的查找时间 |
+| 2 | actionStart(tag: string): void | @since1.0.3 cmd窗口输出开始tag |
+| 3 | actionEnd(tag: string): void | @since1.0.3 cmd窗口输出结束tag |
+
+ 示例代码:
+
+```javascript
+import { describe, it, expect, SysTestKit} from '@ohos/hypium';
+
+export default function existKeywordTest() {
+ describe('existKeywordTest', function () {
+ it('existKeyword',DEFAULT, async function () {
+ console.info("HelloTest");
+ let isExist = await SysTestKit.existKeyword('HelloTest');
+ console.info('isExist ------>' + isExist);
+ })
+ })
+}
+```
+```javascript
+import { describe, it, expect, SysTestKit} from '@ohos/hypium';
+
+export default function actionTest() {
+ describe('actionTest', function () {
+ it('existKeyword',DEFAULT, async function () {
+ let tag = '[MyTest]';
+ SysTestKit.actionStart(tag);
+ //do something
+ SysTestKit.actionEnd(tag);
+ })
+ })
+}
+```
+
+#### 专项能力
+
+- 测试用例属性筛选能力:hypium支持根据用例属性筛选执行指定测试用例,使用方式是先在测试用例上标记用例属性后,再在测试应用的启动shell命令后新增" -s ${Key} ${Value}"。
+
+| Key | 含义说明 | Value取值范围 |
+| -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| level | 用例级别 | "0","1","2","3","4", 例如:-s level 1 |
+| size | 用例粒度 | "small","medium","large", 例如:-s size small |
+| testType | 用例测试类型 | "function","performance","power","reliability","security","global","compatibility","user","standard","safety","resilience", 例如:-s testType function |
+
+ 示例代码
+
+```javascript
+import { describe, it, expect, TestType, Size, Level } from '@ohos/hypium';
+
+export default function attributeTest() {
+ describe('attributeTest', function () {
+ it("testAttributeIt", TestType.FUNCTION | Size.SMALLTEST | Level.LEVEL0, function () {
+ console.info('Hello Test');
+ })
+ })
+}
+```
+
+ 示例命令
+```shell
+XX -s level 1 -s size small -s testType function
+```
+该命令的作用是:筛选测试应用中同时满足a)用例级别是1 b)用例粒度是small c)用例测试类型是function 三个条件的用例执行。
+
+- 测试套/测试用例名称筛选能力(测试套与用例名称用“#”号连接,多个用“,”英文逗号分隔)
+
+| Key | 含义说明 | Value取值范围 |
+| -------- | ----------------------- | -------------------------------------------------------------------------------------------- |
+| class | 指定要执行的测试套&用例 | ${describeName}#${itName},${describeName} , 例如:-s class attributeTest#testAttributeIt |
+| notClass | 指定不执行的测试套&用例 | ${describeName}#${itName},${describeName} , 例如:-s notClass attributeTest#testAttributeIt |
+
+ 示例命令
+```shell
+XX -s class attributeTest#testAttributeIt,abilityTest#testAbilityIt
+```
+该命令的作用是:筛选测试应用中attributeTest测试套下的testAttributeIt测试用例,abilityTest测试套下的testAbilityIt测试用例,只执行这两条用例。
+
+- 其他能力
+
+| 能力项 | Key | 含义说明 | Value取值范围 |
+| ------------ | ------- | ---------------------------- | ---------------------------------------------- |
+| 随机执行能力 | random | 测试套&测试用例随机执行 | true, 不传参默认为false, 例如:-s random true |
+| 空跑能力 | dryRun | 显示要执行的测试用例信息全集 | true , 不传参默认为false,例如:-s dryRun true |
+| 异步超时能力 | timeout | 异步用例执行的超时时间 | 正整数 , 单位ms,例如:-s timeout 5000 |
+
+##### 约束限制
+随机执行能力和空跑能力从npm包1.0.3版本开始支持
+
+#### Mock能力
+
+##### 约束限制
+
+单元测试框架Mock能力从npm包[1.0.1版本](https://repo.harmonyos.com/#/cn/application/atomService/@ohos%2Fhypium/v/1.0.1)开始支持
+
+## 约束
+
+***
+ 本模块首批接口从OpenHarmony SDK API version 8开始支持。
+
+## Hypium开放能力隐私声明
+
+- 我们如何收集和使用您的个人信息
+ 您在使用集成了Hypium开放能力的测试应用时,Hypium不会处理您的个人信息。
+- SDK处理的个人信息
+ 不涉及。
+- SDK集成第三方服务声明
+ 不涉及。
+- SDK数据安全保护
+ 不涉及。
+- SDK版本更新声明
+ 为了向您提供最新的服务,我们会不时更新Hypium版本。我们强烈建议开发者集成使用最新版本的Hypium。
+
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/index.d.ts b/oh_modules/.ohpm/oh_modules/@ohos/hypium/index.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b0b4394a3284c07e873e84c9144cd31889e1863d
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/index.d.ts
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export const DEFAULT = 0B0000
+
+export const when: when;
+
+export enum TestType {
+ FUNCTION = 0B1,
+ PERFORMANCE = 0B1 << 1,
+ POWER = 0B1 << 2,
+ RELIABILITY = 0B1 << 3,
+ SECURITY = 0B1 << 4,
+ GLOBAL = 0B1 << 5,
+ COMPATIBILITY = 0B1 << 6,
+ USER = 0B1 << 7,
+ STANDARD = 0B1 << 8,
+ SAFETY = 0B1 << 9,
+ RESILIENCE = 0B1 << 10
+}
+
+export enum Size {
+ SMALLTEST = 0B1 << 16,
+ MEDIUMTEST = 0B1 << 17,
+ LARGETEST = 0B1 << 18
+}
+
+export enum Level {
+ LEVEL0 = 0B1 << 24,
+ LEVEL1 = 0B1 << 25,
+ LEVEL2 = 0B1 << 26,
+ LEVEL3 = 0B1 << 27,
+ LEVEL4 = 0B1 << 28
+}
+
+export function describe(testSuiteName: string, callback: Function): void
+
+export function beforeEach(callback: Function): void
+
+export function afterEach(callback: Function): void
+
+export function beforeAll(callback: Function): void
+
+export function afterAll(callback: Function): void
+
+export function it(testCaseName: string, attribute: (TestType | Size | Level), callback: Function)
+
+export interface Assert {
+ assertClose(expectValue: number, precision: number): void
+ assertContain(expectValue: any): void
+ assertEqual(expectValue: any): void
+ assertFail(): void
+ assertFalse(): void
+ assertTrue(): void
+ assertInstanceOf(expectValue: string): void
+ assertLarger(expectValue: number): void
+ assertLess(expectValue: number): void
+ assertNull(): void
+ assertThrowError(expectValue: string): void
+ assertUndefined(): void
+ assertLargerOrEqual(expectValue: number):void
+ assertLessOrEqual(expectValue: number):void
+ assertNaN():void
+ assertNegUnlimited(): void
+ assertPosUnlimited(): void
+ not(): Assert;
+ assertDeepEquals(expectValue: any):void
+ assertPromiseIsPending(): void
+ assertPromiseIsRejected(): void
+ assertPromiseIsRejectedWith(expectValue?: any): void
+ assertPromiseIsRejectedWithError(...expectValue): void
+ assertPromiseIsResolved(): void
+ assertPromiseIsResolvedWith(expectValue?: any): void
+}
+
+export function expect(actualValue?: any): Assert
+
+export class ArgumentMatchers {
+ static any;
+ static anyString;
+ static anyBoolean;
+ static anyNumber;
+ static anyObj;
+ static anyFunction;
+ static matchRegexs(Regex: RegExp): void
+}
+
+declare interface when {
+ afterReturn(value: any): any
+ afterReturnNothing(): undefined
+ afterAction(action: any): any
+ afterThrow(e_msg: string): string
+ (argMatchers?: any): when;
+}
+
+export interface VerificationMode {
+ times(count: Number): void
+ never(): void
+ once(): void
+ atLeast(count: Number): void
+ atMost(count: Number): void
+}
+
+export class MockKit {
+ constructor()
+ mockFunc(obj: Object, func: Function): Function
+ mockObject(obj: Object): Object
+ verify(methodName: String, argsArray: Array): VerificationMode
+ ignoreMock(obj: Object, func: Function): void
+ clear(obj: Object): void
+ clearAll(): void
+}
+
+export class SysTestKit {
+ static actionStart(tag: string): void
+ static actionEnd(tag: string): void
+ static existKeyword(keyword: string, timeout?: number): boolean
+}
+
+export class Hypium {
+ static setData(data: {[key: string]: any}): void
+ static setTimeConfig(systemTime: any)
+ static hypiumTest(abilityDelegator: any, abilityDelegatorArguments: any, testsuite: Function): void
+}
\ No newline at end of file
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/index.ets b/oh_modules/.ohpm/oh_modules/@ohos/hypium/index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..355d006f5cd3e7f5e9d1a83374ad1dc0b588d1a0
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/index.ets
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Core from './src/main/core';
+import {ConfigService} from './src/main/module/config/configService'
+import {DEFAULT, TestType, Size, Level, TAG} from './src/main/Constant';
+import DataDriver from './src/main/module/config/DataDriver';
+import ExpectExtend from './src/main/module/assert/ExpectExtend';
+import OhReport from './src/main/module/report/OhReport';
+import SysTestKit from './src/main/module/kit/SysTestKit';
+import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from './src/main/interface';
+import {MockKit, when} from './src/main/module/mock/MockKit';
+import ArgumentMatchers from './src/main/module/mock/ArgumentMatchers';
+
+interface AbilityDelegatorArgs {
+ bundleName: string;
+ parameters: Object;
+ testCaseNames: string;
+ testRunnerClassName: string;
+}
+
+class Hypium {
+ static setData(data:Object) {
+ const core = Core.getInstance();
+ const dataDriver = new DataDriver({data});
+ core.addService('dataDriver', dataDriver);
+ }
+
+ static setTimeConfig(systemTime:Object) {
+ SysTestKit.systemTime = systemTime;
+ }
+
+ static hypiumTest(abilityDelegator:Object, abilityDelegatorArguments:AbilityDelegatorArgs, testsuite:Function) {
+ const core = Core.getInstance();
+ const expectExtend = new ExpectExtend({
+ id: 'extend'
+ });
+ core.addService('expect', expectExtend);
+ const ohReport = new OhReport({
+ delegator: abilityDelegator,
+ abilityDelegatorArguments: abilityDelegatorArguments
+ });
+ SysTestKit.delegator = abilityDelegator;
+ core.addService('report', ohReport);
+ core.init();
+ core.subscribeEvent('spec', ohReport);
+ core.subscribeEvent('suite', ohReport);
+ core.subscribeEvent('task', ohReport);
+ const configService:ConfigService = core.getDefaultService('config');
+ let testParameters:Object = null;
+ if (abilityDelegatorArguments !== null) {
+ testParameters = configService.translateParams(abilityDelegatorArguments.parameters);
+ }
+ console.info(`${TAG}parameters:${JSON.stringify(testParameters)}`);
+ configService.setConfig(testParameters);
+
+ testsuite();
+ core.execute(abilityDelegator);
+ }
+}
+
+export {
+ Hypium,
+ Core,
+ DEFAULT,
+ TestType,
+ Size,
+ Level,
+ DataDriver,
+ ExpectExtend,
+ OhReport,
+ SysTestKit,
+ describe, beforeAll, beforeEach, afterEach, afterAll, it, expect,
+ MockKit, when,
+ ArgumentMatchers
+};
\ No newline at end of file
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/index.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..affc83beb4c94a3aa9440bd69069ebced10c9109
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/index.js
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Core from './src/main/core';
+import {DEFAULT, TestType, Size, Level, TAG} from './src/main/Constant';
+import DataDriver from './src/main/module/config/DataDriver';
+import ExpectExtend from './src/main/module/assert/ExpectExtend';
+import OhReport from './src/main/module/report/OhReport';
+import SysTestKit from './src/main/module/kit/SysTestKit';
+import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from './src/main/interface';
+import {MockKit, when} from './src/main/module/mock/MockKit';
+import ArgumentMatchers from './src/main/module/mock/ArgumentMatchers';
+
+class Hypium {
+ static setData(data) {
+ const core = Core.getInstance();
+ const dataDriver = new DataDriver({data});
+ core.addService('dataDriver', dataDriver);
+ }
+
+ static setTimeConfig(systemTime) {
+ SysTestKit.systemTime = systemTime;
+ }
+
+ static hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) {
+ const core = Core.getInstance();
+ const expectExtend = new ExpectExtend({
+ 'id': 'extend'
+ });
+ core.addService('expect', expectExtend);
+ const ohReport = new OhReport({
+ 'delegator': abilityDelegator,
+ 'abilityDelegatorArguments': abilityDelegatorArguments
+ });
+ SysTestKit.delegator = abilityDelegator;
+ core.addService('report', ohReport);
+ core.init();
+ core.subscribeEvent('spec', ohReport);
+ core.subscribeEvent('suite', ohReport);
+ core.subscribeEvent('task', ohReport);
+ const configService = core.getDefaultService('config');
+
+ let testParameters = {};
+ if (abilityDelegatorArguments !== null) {
+ testParameters = configService.translateParams(abilityDelegatorArguments.parameters);
+ }
+ console.info(`${TAG}parameters:${JSON.stringify(testParameters)}`);
+ configService.setConfig(testParameters);
+
+ testsuite();
+ core.execute(abilityDelegator);
+ }
+}
+
+export {
+ Hypium,
+ Core,
+ DEFAULT,
+ TestType,
+ Size,
+ Level,
+ DataDriver,
+ ExpectExtend,
+ OhReport,
+ SysTestKit,
+ describe, beforeAll, beforeEach, afterEach, afterAll, it, expect,
+ MockKit, when,
+ ArgumentMatchers
+};
\ No newline at end of file
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/oh-package.json5 b/oh_modules/.ohpm/oh_modules/@ohos/hypium/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..586263cbcdd5006e495ee4176cdec5b96812dcae
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/oh-package.json5
@@ -0,0 +1,11 @@
+{
+ "name": "@ohos/hypium",
+ "version": "1.0.9",
+ "description": "A unit test framework for OpenHarmony application",
+ "main": "index.js",
+ "keywords": [],
+ "author": "huawei",
+ "license": "Apache-2.0",
+ "dependencies": {
+ }
+}
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/Constant.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/Constant.js
new file mode 100644
index 0000000000000000000000000000000000000000..13f68499c8688027eb2dc49c6dc4028610ab480c
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/Constant.js
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * define the testcase type : TestType, Size , Level
+ */
+export const TAG = '[Hypium]';
+
+export const DEFAULT = 0B0000;
+
+export class TestType {
+ static FUNCTION = 0B1;
+ static PERFORMANCE = 0B1 << 1;
+ static POWER = 0B1 << 2;
+ static RELIABILITY = 0B1 << 3;
+ static SECURITY = 0B1 << 4;
+ static GLOBAL = 0B1 << 5;
+ static COMPATIBILITY = 0B1 << 6;
+ static USER = 0B1 << 7;
+ static STANDARD = 0B1 << 8;
+ static SAFETY = 0B1 << 9;
+ static RESILIENCE = 0B1 << 10;
+}
+
+export class Size {
+ static SMALLTEST = 0B1 << 16;
+ static MEDIUMTEST = 0B1 << 17;
+ static LARGETEST = 0B1 << 18;
+}
+
+export class Level {
+ static LEVEL0 = 0B1 << 24;
+ static LEVEL1 = 0B1 << 25;
+ static LEVEL2 = 0B1 << 26;
+ static LEVEL3 = 0B1 << 27;
+ static LEVEL4 = 0B1 << 28;
+}
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/core.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/core.js
new file mode 100644
index 0000000000000000000000000000000000000000..cfcb5f17287208f5e6869b4248faf6c9093002d9
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/core.js
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {SuiteService, SpecService, ExpectService, ReportService} from './service';
+import {ConfigService} from './module/config/configService';
+import {SpecEvent, TaskEvent, SuiteEvent} from './event';
+
+/**
+ * core service for execute testcase.
+ */
+class Core {
+ static getInstance() {
+ if (!this.instance) {
+ this.instance = new Core();
+ }
+ return this.instance;
+ }
+
+ constructor() {
+ this.instance = null;
+ this.services = {
+ suite: {},
+ spec: {},
+ config: {},
+ expect: {},
+ log: {},
+ report: {}
+
+ };
+ this.events = {
+ suite: {},
+ spec: {},
+ task: {}
+ };
+ }
+
+ addService(name, service) {
+ let serviceObj = {};
+ if (!this.services[name]) {
+ this.services[name] = serviceObj;
+ } else {
+ serviceObj = this.services[name];
+ }
+ serviceObj[service.id] = service;
+ }
+
+ getDefaultService(name) {
+ return this.services[name].default;
+ }
+
+ getServices(name) {
+ return this.services[name];
+ }
+
+ registerEvent(serviceName, event) {
+ let eventObj = {};
+ if (!this.events[serviceName]) {
+ this.events[serviceName] = eventObj;
+ } else {
+ eventObj = this.events[serviceName];
+ }
+ eventObj[event.id] = event;
+ }
+
+ unRegisterEvent(serviceName, eventID) {
+ const eventObj = this.events[serviceName];
+ if (eventObj) {
+ delete eventObj[eventID];
+ }
+ }
+
+ subscribeEvent(serviceName, serviceObj) {
+ const eventObj = this.events[serviceName];
+ if (eventObj) {
+ for (const attr in eventObj) {
+ eventObj[attr]['subscribeEvent'](serviceObj);
+ }
+ }
+ }
+
+ async fireEvents(serviceName, eventName) {
+ const eventObj = this.events[serviceName];
+ if (!eventObj) {
+ return;
+ }
+ for (const attr in eventObj) {
+ await eventObj[attr][eventName]();
+ }
+ }
+
+ addToGlobal(apis) {
+ if (typeof globalThis !== 'undefined') {
+ for (let api in apis) {
+ globalThis[api] = apis[api];
+ }
+ }
+ for (const api in apis) {
+ this[api] = apis[api];
+ }
+ }
+
+ init() {
+ this.addService('suite', new SuiteService({id: 'default'}));
+ this.addService('spec', new SpecService({id: 'default'}));
+ this.addService('expect', new ExpectService({id: 'default'}));
+ this.addService('report', new ReportService({id: 'default'}));
+ this.addService('config', new ConfigService({id: 'default'}));
+ this.registerEvent('task', new TaskEvent({id: 'default', coreContext: this}));
+ this.registerEvent('suite', new SuiteEvent({id: 'default', coreContext: this}));
+ this.registerEvent('spec', new SpecEvent({id: 'default', coreContext: this}));
+ this.subscribeEvent('spec', this.getDefaultService('report'));
+ this.subscribeEvent('suite', this.getDefaultService('report'));
+ this.subscribeEvent('task', this.getDefaultService('report'));
+ const context = this;
+ for (const key in this.services) {
+ const serviceObj = this.services[key];
+ for (const serviceID in serviceObj) {
+ const service = serviceObj[serviceID];
+ service.init(context);
+
+ if (typeof service.apis !== 'function') {
+ continue;
+ }
+ const apis = service.apis();
+ if (apis) {
+ this.addToGlobal(apis);
+ }
+ }
+ }
+ }
+
+ execute(abilityDelegator) {
+ const suiteService = this.getDefaultService('suite');
+ const configService = this.getDefaultService('config');
+ if (configService['dryRun'] === 'true') {
+ (async function () {
+ await suiteService.dryRun(abilityDelegator);
+ })();
+ return;
+ }
+ setTimeout(() => {
+ suiteService.execute();
+ }, 10);
+ }
+}
+
+export default Core;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/event.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/event.js
new file mode 100644
index 0000000000000000000000000000000000000000..1333a1c483f9a2aa1c45e133b1d3cbbc7cdb8346
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/event.js
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class SpecEvent {
+ constructor(attr) {
+ this.id = attr.id;
+ this.coreContext = attr.context;
+ this.eventMonitors = [];
+ }
+
+ subscribeEvent(service) {
+ this.eventMonitors.push(service);
+ }
+
+ async specStart() {
+ for (const monitor of this.eventMonitors) {
+ await monitor['specStart']();
+ }
+ }
+
+ async specDone() {
+ for (const monitor of this.eventMonitors) {
+ await monitor['specDone']();
+ }
+ }
+}
+
+class SuiteEvent {
+ constructor(attr) {
+ this.id = attr.id;
+ this.suiteContext = attr.coreContext;
+ this.eventMonitors = [];
+ }
+
+ subscribeEvent(service) {
+ this.eventMonitors.push(service);
+ }
+
+ async suiteStart() {
+ for (const monitor of this.eventMonitors) {
+ await monitor['suiteStart']();
+ }
+ }
+
+ async suiteDone() {
+ for (const monitor of this.eventMonitors) {
+ await monitor['suiteDone']();
+ }
+ }
+}
+
+class TaskEvent {
+ constructor(attr) {
+ this.id = attr.id;
+ this.coreContext = attr.coreContext;
+ this.eventMonitors = [];
+ }
+
+ subscribeEvent(service) {
+ this.eventMonitors.push(service);
+ }
+
+ async taskStart() {
+ for (const monitor of this.eventMonitors) {
+ await monitor['taskStart']();
+ }
+ }
+
+ async taskDone() {
+ for (const monitor of this.eventMonitors) {
+ await monitor['taskDone']();
+ }
+ }
+
+ incorrectFormat() {
+ for (const monitor of this.eventMonitors) {
+ monitor['incorrectFormat']();
+ }
+ }
+}
+
+export {SpecEvent, TaskEvent, SuiteEvent};
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/interface.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/interface.js
new file mode 100644
index 0000000000000000000000000000000000000000..40398c849d55cd76ab64fcba26899b547e2a3c97
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/interface.js
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Core from './core';
+
+const core = Core.getInstance();
+
+const describe = function (desc, func) {
+ return Reflect.has(core, 'describe') ? core.describe(desc, func) : (desc, func) => { };
+};
+const it = function (desc, filter, func) {
+ return Reflect.has(core, 'it') ? core.it(desc, filter, func) : (desc, filter, func) => { };
+};
+const beforeEach = function (func) {
+ return Reflect.has(core, 'beforeEach') ? core.beforeEach(func) : (func) => { };
+};
+const afterEach = function (func) {
+ return Reflect.has(core, 'afterEach') ? core.afterEach(func) : (func) => { };
+};
+const beforeAll = function (func) {
+ return Reflect.has(core, 'beforeAll') ? core.beforeAll(func) : (func) => { };
+};
+const afterAll = function (func) {
+ return Reflect.has(core, 'afterAll') ? core.afterAll(func) : (func) => { };
+};
+const expect = function (actualValue) {
+ return Reflect.has(core, 'expect') ? core.expect(actualValue) : (actualValue) => { };
+};
+
+export {
+ describe, it, beforeAll, beforeEach, afterEach, afterAll, expect
+};
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/ExpectExtend.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/ExpectExtend.js
new file mode 100644
index 0000000000000000000000000000000000000000..d10d15e6f9955c6d04610101f8766c951ee1a35d
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/ExpectExtend.js
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import assertNull from './assertNull';
+import assertClose from './assertClose';
+import assertContain from './assertContain';
+import assertLess from './assertLess';
+import assertLarger from './assertLarger';
+import assertFail from './assertFail';
+import assertUndefined from './assertUndefined';
+import assertFalse from './assertFalse';
+import assertInstanceOf from './assertInstanceOf';
+import assertThrowError from './assertThrowError';
+import assertLargerOrEqual from './assertLargerOrEqual'
+import assertLessOrEqual from './assertLessOrEqual'
+import assertNaN from './assertNaN'
+import assertNegUnlimited from './assertNegUnlimited'
+import assertPosUnlimited from './assertPosUnlimited'
+import assertDeepEquals from './deepEquals/assertDeepEquals'
+import assertPromiseIsPending from './assertPromiseIsPending';
+import assertPromiseIsRejected from './assertPromiseIsRejected';
+import assertPromiseIsRejectedWith from './assertPromiseIsRejectedWith';
+import assertPromiseIsRejectedWithError from './assertPromiseIsRejectedWithError';
+import assertPromiseIsResolved from './assertPromiseIsResolved';
+import assertPromiseIsResolvedWith from './assertPromiseIsResolvedWith';
+class ExpectExtend {
+ constructor(attr) {
+ this.id = attr.id;
+ this.matchers = {};
+ }
+
+ extendsMatchers() {
+ this.matchers.assertNull = assertNull;
+ this.matchers.assertClose = assertClose;
+ this.matchers.assertContain = assertContain;
+ this.matchers.assertLess = assertLess;
+ this.matchers.assertLarger = assertLarger;
+ this.matchers.assertFail = assertFail;
+ this.matchers.assertUndefined = assertUndefined;
+ this.matchers.assertFalse = assertFalse;
+ this.matchers.assertInstanceOf = assertInstanceOf;
+ this.matchers.assertThrowError = assertThrowError;
+ this.matchers.assertLargerOrEqual = assertLargerOrEqual;
+ this.matchers.assertLessOrEqual = assertLessOrEqual;
+ this.matchers.assertNaN = assertNaN;
+ this.matchers.assertNegUnlimited = assertNegUnlimited;
+ this.matchers.assertPosUnlimited = assertPosUnlimited;
+ this.matchers.assertDeepEquals = assertDeepEquals;
+ this.matchers.assertPromiseIsPending = assertPromiseIsPending;
+ this.matchers.assertPromiseIsRejected = assertPromiseIsRejected;
+ this.matchers.assertPromiseIsRejectedWith = assertPromiseIsRejectedWith;
+ this.matchers.assertPromiseIsRejectedWithError = assertPromiseIsRejectedWithError;
+ this.matchers.assertPromiseIsResolved = assertPromiseIsResolved;
+ this.matchers.assertPromiseIsResolvedWith = assertPromiseIsResolvedWith;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ this.extendsMatchers();
+ const expectService = this.coreContext.getDefaultService('expect');
+ expectService.addMatchers(this.matchers);
+ }
+
+ apis() {
+ return {
+ 'expect': function (actualValue) {
+ return this.coreContext.getDefaultService('expect').expect(actualValue);
+ }
+ };
+ }
+}
+
+export default ExpectExtend;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertClose.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertClose.js
new file mode 100644
index 0000000000000000000000000000000000000000..63635bea5bf1298776de565260e0e0babae56857
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertClose.js
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertClose(actualValue, expected) {
+ console.log('expected:' + expected[0] + ',precision:' + expected[1]);
+ if (actualValue === null && expected[0] === null) {
+ throw new Error('actualValue and expected can not be both null!!!');
+ }
+ let result;
+ let diff = Math.abs(expected[0] - actualValue);
+ let actualAbs = Math.abs(actualValue);
+ if ((actualAbs - 0) === 0) {
+ if ((diff - 0) === 0) {
+ result = true;
+ } else {
+ result = false;
+ }
+ } else if (diff / actualAbs < expected[1]) {
+ result = true;
+ } else {
+ result = false;
+ }
+ return {
+ pass: result,
+ message: '|' + actualValue + ' - ' + expected[0] + '|/' + actualValue + ' is not less than ' + expected[1]
+ };
+}
+
+export default assertClose;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertContain.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertContain.js
new file mode 100644
index 0000000000000000000000000000000000000000..7fba0d9755503e5e926f6c1a4e425e0d1cf47570
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertContain.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertContain(actualValue, expect) {
+ let result = false;
+ if (Object.prototype.toString.call(actualValue).indexOf('Array')) {
+ for (let i in actualValue) {
+ if (actualValue[i] == expect[0]) {
+ result = true;
+ }
+ }
+ }
+ let type = Object.prototype.toString.call(actualValue);
+ if (type === '[object String]') {
+ result = actualValue.indexOf(expect[0]) >= 0;
+ }
+ return {
+ pass: result,
+ message: 'expect false, ' + actualValue + ' do not have ' + expect[0]
+ };
+}
+
+export default assertContain;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertFail.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertFail.js
new file mode 100644
index 0000000000000000000000000000000000000000..8ab4ac5caef712c75c4eac49dfbbb91d33669d9a
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertFail.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertFail() {
+ return {
+ pass: false,
+ message: 'fail '
+ };
+}
+
+export default assertFail;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertFalse.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertFalse.js
new file mode 100644
index 0000000000000000000000000000000000000000..c5008e94f4b2ce13ed35b604811793c76b542347
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertFalse.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertFalse(actualValue) {
+ return {
+ pass: (actualValue) === false,
+ message: 'expect false, actualValue is ' + actualValue
+ };
+}
+
+export default assertFalse;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertInstanceOf.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertInstanceOf.js
new file mode 100644
index 0000000000000000000000000000000000000000..1e11b93f7251c67f5455c5007cd7be268aa53b32
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertInstanceOf.js
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertInstanceOf(actualValue, expected) {
+ if (Object.prototype.toString.call(actualValue) == '[object ' + expected[0] + ']') {
+ return {
+ pass: true
+ };
+ } else {
+ return {
+ pass: false,
+ message: actualValue + ' is ' + Object.prototype.toString.call(actualValue) + 'not ' + expected[0]
+ };
+ }
+}
+
+export default assertInstanceOf;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertLarger.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertLarger.js
new file mode 100644
index 0000000000000000000000000000000000000000..a74f4a8cedaf3add9c2dc2d3799081a83198732f
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertLarger.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertLarger(actualValue, expected) {
+ return {
+ pass: (actualValue) > expected[0],
+ message: (actualValue) + ' is not larger than ' + expected[0]
+ };
+}
+
+export default assertLarger;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertLargerOrEqual.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertLargerOrEqual.js
new file mode 100644
index 0000000000000000000000000000000000000000..e847e6c217364b7f69c173c66fb98d10efc45ef1
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertLargerOrEqual.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertLargerOrEqual(actualValue, expected) {
+ return {
+ pass: (actualValue) >= expected[0],
+ message: (actualValue) + ' is not larger than ' + expected[0]
+ };
+}
+
+export default assertLargerOrEqual;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertLess.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertLess.js
new file mode 100644
index 0000000000000000000000000000000000000000..17e84b0abaeb20804048a5a15c19e0603634846d
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertLess.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertLess(actualValue, expected) {
+ return {
+ pass: (actualValue) < expected[0],
+ message: (actualValue) + ' is not less than ' + expected[0]
+ };
+}
+
+export default assertLess;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertLessOrEqual.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertLessOrEqual.js
new file mode 100644
index 0000000000000000000000000000000000000000..f754f97ffa9d24e7852efe2423a1dd35d448af82
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertLessOrEqual.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertLessOrEqual(actualValue, expected) {
+ return {
+ pass: (actualValue) <= expected[0],
+ message: (actualValue) + ' is not less than ' + expected[0]
+ };
+}
+
+export default assertLessOrEqual;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertNaN.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertNaN.js
new file mode 100644
index 0000000000000000000000000000000000000000..8d45d6a93b86c5ed325a68b32ff014835993a58e
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertNaN.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertNaN(actualValue) {
+ return {
+ pass: actualValue !== actualValue,
+ message: 'expect NaN, actualValue is ' + actualValue
+ };
+}
+
+export default assertNaN;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertNegUnlimited.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertNegUnlimited.js
new file mode 100644
index 0000000000000000000000000000000000000000..ceac555afc826e057970e6cfe9c73b322c672aa2
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertNegUnlimited.js
@@ -0,0 +1,23 @@
+/*
+* Copyright (c) 2022 Huawei Device Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+function assertNegUnlimited(actualValue) {
+ return {
+ pass: actualValue === Number.NEGATIVE_INFINITY,
+ message: 'Expected actualValue not to be -Infinity. actualValue is,' + actualValue
+ };
+}
+
+export default assertNegUnlimited;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertNull.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertNull.js
new file mode 100644
index 0000000000000000000000000000000000000000..53a7bad827323a98d3302a4e7eea679551b459c5
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertNull.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertNull(actualValue) {
+ return {
+ pass: (actualValue) === null,
+ message: 'expect null, actualValue is ' + (actualValue)
+ };
+}
+
+export default assertNull;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPosUnlimited.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPosUnlimited.js
new file mode 100644
index 0000000000000000000000000000000000000000..6e68c0e2b6c499f4dc3dd56c13e9ea1073a3c54c
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPosUnlimited.js
@@ -0,0 +1,23 @@
+/*
+* Copyright (c) 2022 Huawei Device Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+function assertPosUnlimited(actualValue) {
+ return {
+ pass: actualValue === Number.POSITIVE_INFINITY,
+ message: 'Expected actualValue is POSITIVE_INFINITY. actualValue is,' + actualValue
+ };
+}
+
+export default assertPosUnlimited;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsPending.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsPending.js
new file mode 100644
index 0000000000000000000000000000000000000000..7e2ca2ce14d50c39554fc1157d6d4eb9329d5c39
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsPending.js
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import isPromiseLike from './isPromiseLike';
+
+function assertPromiseIsPending(actualPromise) {
+ if (!isPromiseLike(actualPromise)) {
+ return Promise.reject().then(function () {
+ }, function () {
+ return {pass: false, message: 'Expected not be called on a promise.'};
+ });
+ }
+ const helper = {};
+ return Promise.race([actualPromise, Promise.resolve(helper)]).then(
+ function (got) {
+ return helper === got ? {pass: true, message: 'actualValue is isPending'}
+ : {
+ pass: false,
+ message: 'expect isPending, actualValue is resolve'
+ };
+ },
+ function () {
+ return {
+ pass: false
+ , message: 'expect isPending, actualValue is reject'
+ };
+ });
+}
+
+export default assertPromiseIsPending;
\ No newline at end of file
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejected.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejected.js
new file mode 100644
index 0000000000000000000000000000000000000000..eb8e65c7d70d5750a9ccebb55c2cf5049cf144fc
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejected.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import isPromiseLike from './isPromiseLike';
+
+function assertPromiseIsRejected(actualPromise) {
+ if (!isPromiseLike(actualPromise)) {
+ return Promise.reject().then(function () {
+ }, function () {
+ return {pass: false, message: 'Expected not be called on a promise.'};
+ });
+ }
+ const helper = {};
+ return Promise.race([actualPromise, Promise.resolve(helper)]).then(
+ function (got) {
+ return {
+ pass: false,
+ message: 'expect isRejected, but actualValue is '
+ + (helper === got ? 'isPending' : 'resolve')
+ };
+ },
+ function () {
+ return {pass: true, message: 'actualValue is isRejected'};
+ }
+ );
+}
+
+export default assertPromiseIsRejected;
\ No newline at end of file
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWith.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWith.js
new file mode 100644
index 0000000000000000000000000000000000000000..48eaf7859279a70ea2ad85509296b5da1c7b69f9
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWith.js
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import isPromiseLike from './isPromiseLike';
+
+function assertPromiseIsRejectedWith(actualPromise, expectedValue) {
+
+ if (!isPromiseLike(actualPromise)) {
+ return Promise.reject().then(function () {
+ }, function () {
+ return {pass: false, message: 'Expected not be called on a promise.'};
+ });
+ }
+
+ function tips(passed) {
+ return ('Expected a promise ' + (passed ? 'not ' : '') +
+ 'to be rejected with ' + JSON.stringify(expectedValue[0]));
+ }
+
+ const helper = {};
+ return Promise.race([actualPromise, Promise.resolve(helper)]).then(
+ function (got) {
+ return {
+ pass: false,
+ message: tips(false) + ' but actualValue is '
+ + (helper === got ? 'isPending' : 'resolve')
+ };
+ },
+ function (actualValue) {
+ if (JSON.stringify(actualValue) == JSON.stringify(expectedValue[0])) {
+ return {
+ pass: true,
+ message: 'actualValue was rejected with ' + JSON.stringify(actualValue) + '.'
+ };
+ } else {
+ return {
+ pass: false,
+ message: tips(false) + ' but it was rejected with ' + JSON.stringify(actualValue) + '.'
+ };
+ }
+ }
+ );
+}
+
+export default assertPromiseIsRejectedWith;
\ No newline at end of file
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWithError.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWithError.js
new file mode 100644
index 0000000000000000000000000000000000000000..20f236fc11dd66f270322efa12a1b3f6b543407c
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWithError.js
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import isPromiseLike from './isPromiseLike';
+
+function assertPromiseIsRejectedWithError(actualPromise, expectedValue) {
+ if (!isPromiseLike(actualPromise)) {
+ return Promise.reject().then(function () {
+ }, function () {
+ return {pass: false, message: 'Expected not be called on a promise.'};
+ });
+ }
+ const helper = {};
+ return Promise.race([actualPromise, Promise.resolve(helper)]).then(
+ function (got) {
+ return {
+ pass: false,
+ message: 'Expected a promise to be rejected but actualValue is '
+ + (helper === got ? 'isPending' : 'resolve')
+ };
+ },
+ function (actualValue) {
+ return matchError(actualValue, expectedValue);
+ }
+ );
+
+}
+
+function matchError(actualValue, expectedValue) {
+ if (expectedValue.length == 1 && typeof expectedValue[0] === 'function') {
+ if (expectedValue[0].name === actualValue.__proto__.name) {
+ return {pass: true, message: 'actual error type is ' + actualValue.name + '.'};
+ }
+ return {pass: false, message: `except error type is ${expectedValue[0].name},but actual is ${actualValue.name}.`};
+ }
+
+ if (expectedValue.length == 1 && typeof expectedValue[0] === 'string') {
+ if (expectedValue[0] === actualValue.message) {
+ return {pass: true, message: `actual error message is ${actualValue.message}.`};
+ }
+ return {pass: false, message: `except error message ${expectedValue[0]},but actual is ${actualValue.message}.`};
+ }
+
+ if (expectedValue.length == 1) {
+ return {pass: false, message: 'When only one parameter, it should be error type or error message.'};
+ }
+
+ if (expectedValue.length == 2 && typeof expectedValue[0] === 'function' && expectedValue[0].name === actualValue.name) {
+ if (typeof expectedValue[1] === 'string' && actualValue.message === expectedValue[1]) {
+ return {pass: true, message: 'actual error message is ' + actualValue.message + '.'};
+ }
+ return {pass: false, message: `except error message is ${expectedValue[1]},but actual is ${actualValue.message}.`};
+ }
+
+ if (expectedValue.length == 2 && typeof expectedValue[0] === 'function' && expectedValue[0].name !== actualValue.name) {
+ if (typeof expectedValue[1] === 'string' && actualValue.message === expectedValue[1]) {
+ return {pass: false, message: `except error type is ${expectedValue[0].name},but actual is ${actualValue.name}.`};
+ }
+ return {pass: false, message: 'except error type and message are incorrect.'};
+ }
+ if (expectedValue.length > 2) {
+ return {pass: false, message: 'Up to two parameters are supported.'};
+ }
+}
+
+export default assertPromiseIsRejectedWithError;
\ No newline at end of file
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolved.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolved.js
new file mode 100644
index 0000000000000000000000000000000000000000..855426ca79e5002428e53d4fcb5f843cdf7119f7
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolved.js
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import isPromiseLike from './isPromiseLike';
+
+function assertPromiseIsResolved(actualPromise) {
+ if (!isPromiseLike(actualPromise)) {
+ return Promise.reject().then(function () {
+ }, function () {
+ return {pass: false, message: 'Expected not be called on a promise.'};
+ });
+ }
+
+ const helper = {};
+ return Promise.race([actualPromise, Promise.resolve(helper)]).then(
+ function (got) {
+ return helper === got ? {
+ pass: false,
+ message: 'expect resolve, actualValue is isPending'
+ }
+ : {pass: true, message: 'actualValue is isResolved'};
+ },
+ function (rej) {
+ return {
+ pass: false,
+ message: 'Expected a promise to be resolved but it was ' +
+ 'rejected with ' + JSON.stringify(rej) + '.'
+ };
+ }
+ );
+}
+
+export default assertPromiseIsResolved;
\ No newline at end of file
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolvedWith.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolvedWith.js
new file mode 100644
index 0000000000000000000000000000000000000000..d5eb01e32491b281a1e1d650a307723253a61e39
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolvedWith.js
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import isPromiseLike from './isPromiseLike';
+
+function assertPromiseIsResolvedWith(actualPromise, expectedValue) {
+ if (!isPromiseLike(actualPromise)) {
+ return Promise.reject().then(function () {
+ }, function () {
+ return {pass: false, message: 'Expected not be called on a promise.'};
+ });
+ }
+
+ function tips(passed) {
+ return (
+ 'Expected a promise ' + (passed ? 'not ' : '') +
+ 'to be resolved with ' + JSON.stringify(expectedValue[0]));
+ }
+
+ const helper = {};
+ return Promise.race([actualPromise, Promise.resolve(helper)]).then(
+ function (got) {
+ if (helper === got) {
+ return {pass: false, message: 'expect resolve, actualValue is isPending'};
+ }
+ if (JSON.stringify(got) == JSON.stringify(expectedValue[0])) {
+ return {
+ pass: true,
+ message: 'actualValue was resolved with ' + JSON.stringify(got) + '.'
+ };
+ }
+ return {
+ pass: false,
+ message: tips(false) + ' but it was resolved with ' +
+ JSON.stringify(got) + '.'
+ };
+ },
+ function (rej) {
+ return {
+ pass: false,
+ message: tips(false) + ' but it was rejected with ' + JSON.stringify(rej) + '.'
+ };
+ }
+ );
+}
+
+export default assertPromiseIsResolvedWith;
\ No newline at end of file
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertThrowError.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertThrowError.js
new file mode 100644
index 0000000000000000000000000000000000000000..749cab0daee3f156909f60c9375146c23d7aa322
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertThrowError.js
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertThrowError(actualValue, expected) {
+ let result = false;
+ let err;
+ if (typeof actualValue !== 'function') {
+ throw new Error('actualValue is not a function');
+ }
+ try {
+ actualValue();
+ return {
+ pass: result,
+ message: ' An error is not thrown while it is expected!'
+ };
+ } catch (e) {
+ err = e;
+ }
+
+ if (err instanceof Error) {
+ console.log(err.message);
+ if (err.message == expected[0]) {
+ result = true;
+ }
+ }
+ return {
+ pass: result,
+ message: 'expected throw failed , ' + err.message + ' is not ' + expected[0]
+ };
+}
+
+export default assertThrowError;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertUndefined.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertUndefined.js
new file mode 100644
index 0000000000000000000000000000000000000000..61f092d715dd1630297518b59ff13ef0940991e1
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/assertUndefined.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertUndefined(actualValue) {
+ return {
+ pass: undefined === (actualValue),
+ message: 'expect Undefined, actualValue is ' + (actualValue)
+ };
+}
+
+export default assertUndefined;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/DeepTypeUtils.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/DeepTypeUtils.js
new file mode 100644
index 0000000000000000000000000000000000000000..627fb3b3ae7e315808b5ee2927d4bfbf17cc64b2
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/DeepTypeUtils.js
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class DeepTypeUtils {
+ static getType_(value) {
+ return Object.prototype.toString.apply(value);
+ }
+ static isA_(typeName, value) {
+ return this.getType_(value) === '[object ' + typeName + ']';
+ }
+ static isAsymmetricEqualityTester_(obj) {
+ return obj ? this.isA_('Function', obj.asymmetricMatch) : false;
+ }
+
+ /**
+ * 是否是function
+ * @param value
+ */
+ static isFunction_(value) {
+ return this.isA_('Function', value);
+ }
+
+ /**
+ * 是否是undefined
+ * @param obj
+ */
+ static isUndefined(obj) {
+ return obj === void 0;
+ }
+
+ /**
+ * 是否是Node
+ * @param obj
+ */
+ static isDomNode(obj) {
+ return obj !== null &&
+ typeof obj === 'object' &&
+ typeof obj.nodeType === 'number' &&
+ typeof obj.nodeName === 'string';
+ }
+
+ /**
+ * 是否是promise对象
+ * @param obj
+ */
+ static isPromise (obj) {
+ return !!obj && obj.constructor === Promise;
+ };
+ /**
+ * 是否是map对象
+ * @param obj
+ */
+ static isMap(obj) {
+ return (
+ obj !== null &&
+ typeof obj !== 'undefined' &&
+ obj.constructor === Map
+ );
+ }
+
+ /**
+ * 是否是set对象
+ * @param obj 对象
+ */
+ static isSet(obj) {
+ return (
+ obj !== null &&
+ typeof obj !== 'undefined' &&
+ obj.constructor === Set
+ );
+ }
+
+ /**
+ * 对象是否有key属性
+ * @param obj 对象
+ * @param key 对象属性名称
+ */
+ static has(obj, key) {
+ return Object.prototype.hasOwnProperty.call(obj, key);
+ }
+
+ /**
+ * 获取对象的自有属性
+ * @param obj 对象
+ * @param isArray 是否是数组,[object Array]
+ */
+ static keys(obj, isArray) {
+ const extraKeys = [];
+ // 获取对象所有属性
+ const allKeys = this.getAllKeys(obj);
+ if (!isArray) {
+ return allKeys;
+ }
+ if (allKeys.length === 0) {
+ return allKeys;
+ }
+ for (const k of allKeys) {
+ if (typeof k === 'symbol' || !/^[0-9]+$/.test(k)) {
+ extraKeys.push(k);
+ }
+ }
+ return extraKeys;
+ }
+
+ /**
+ * 获取obj对象的所有属性
+ * @param obj obj对象
+ */
+ static getAllKeys(obj) {
+ const keys = [];
+ for (let key in obj) {
+ if(this.has(obj, key)) {
+ keys.push(key);
+ }
+ }
+ const symbols = Object.getOwnPropertySymbols(obj);
+ for (const sym of symbols) {
+ if (obj.propertyIsEnumerable(sym)) {
+ keys.push(sym);
+ }
+ }
+ return keys;
+ }
+
+}
+export default DeepTypeUtils;
\ No newline at end of file
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/assertDeepEquals.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/assertDeepEquals.js
new file mode 100644
index 0000000000000000000000000000000000000000..482e28e6af45482f8c2d9d0f61130730b07eba70
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/assertDeepEquals.js
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import DeepTypeUtils from './DeepTypeUtils'
+function assertDeepEquals(actualValue, expected) {
+ console.log('actualValue:' + actualValue + ',expected:' + expected[0]);
+ let result = eq(actualValue, expected[0],[], [])
+ let msg = logMsg(actualValue, expected[0]);
+ return {
+ pass: result,
+ message: msg
+ };
+}
+
+/**
+ * 获取失败显示日志
+ * @param actualValue 实际对象
+ * @param expected 期待比较对象
+ */
+function logMsg(actualValue, expected) {
+ // 获取a的对象名称
+ const aClassName = Object.prototype.toString.call(actualValue);
+ const bClassName = Object.prototype.toString.call(expected);
+ let actualMsg;
+ let expectMsg;
+ if(aClassName == "[object Function]") {
+ actualMsg = "actualValue Function"
+ }else if(aClassName == "[object Promise]") {
+ actualMsg = "actualValue Promise"
+ }else if(aClassName == "[object Set]" || aClassName == "[object Map]") {
+ actualMsg = JSON.stringify(Array.from(actualValue));;
+ }else if(aClassName == "[object RegExp]") {
+ actualMsg = JSON.stringify(actualValue.source.replace("\\",""));;
+ }else if(aClassName == "[object BigInt]") {
+ actualMsg = actualValue;
+ }
+ else{
+ actualMsg = JSON.stringify(actualValue);
+ }
+ if(bClassName == "[object Function]") {
+ expectMsg = "expected Function"
+ }else if(bClassName == "[object Promise]") {
+ expectMsg = "expected Promise"
+ }else if(bClassName == "[object Set]" || bClassName == "[object Map]") {
+ expectMsg = JSON.stringify(Array.from(expected));
+ }else if(bClassName == "[object RegExp]") {
+ expectMsg = JSON.stringify(expected.source.replace("\\",""));;
+ }else if(bClassName == "[object BigInt]") {
+ expectMsg = expected;
+ }
+ else{
+ expectMsg = JSON.stringify(expected);
+ }
+ return actualMsg + " is not deep equal " + expectMsg;
+}
+
+function eq(a, b, aStack, bStack) {
+ let result = true;
+ console.log('a is:' + a + ',b is:' + b);
+ const asymmetricResult = asymmetricMatch_(a,b);
+ if (!DeepTypeUtils.isUndefined(asymmetricResult)) {
+ return asymmetricResult;
+ }
+
+ if (a instanceof Error && b instanceof Error) {
+ result = a.message == b.message;
+ return result;
+ }
+
+ if (a === b) {
+ result = a !== 0 || 1 / a == 1 / b;
+ return result;
+ }
+
+ if (a === null || b === null) {
+ result = a === b;
+ return result;
+ }
+ // 获取a的对象名称
+ const aClassName = Object.prototype.toString.call(a);
+ const bClassName = Object.prototype.toString.call(b);
+ console.log('aClassName is:' + aClassName);
+ console.log('bClassName is:' + bClassName);
+ // 不同类型不同对象
+ if (aClassName != bClassName) {
+ return false;
+ }
+ // 俩个string对象
+ if(aClassName === '[object String]') {
+ result = a == String(b);
+ return result;
+ }
+ // 俩个Number对象
+ if(aClassName === '[object Number]') {
+ result = a != +a ? b != +b : a === 0 && b === 0 ? 1 / a == 1 / b : a == +b;
+ return result;
+ }
+
+ if(aClassName === '[object Date]' || aClassName === '[object Boolean]') {
+ result = +a == +b;
+ return result;
+ }
+
+ // 数组
+ if(aClassName === '[object ArrayBuffer]') {
+ return eq(new Uint8Array(a), new Uint8Array(b), aStack, bStack);
+ }
+
+ // 正则表达式
+ if(aClassName === '[object RegExp]') {
+ return (
+ a.source == b.source &&
+ a.global == b.global &&
+ a.multiline == b.multiline &&
+ a.ignoreCase == b.ignoreCase
+ );
+ }
+
+ if (typeof a != 'object' || typeof b != 'object') {
+ return false;
+ }
+
+ const aIsDomNode = DeepTypeUtils.isDomNode(a);
+ const bIsDomNode = DeepTypeUtils.isDomNode(b);
+ if (aIsDomNode && bIsDomNode) {
+ // At first try to use DOM3 method isEqualNode
+ result = a.isEqualNode(b);
+ return result;
+ }
+ if (aIsDomNode || bIsDomNode) {
+ return false;
+ }
+ const aIsPromise = DeepTypeUtils.isPromise(a);
+ const bIsPromise = DeepTypeUtils.isPromise(b);
+ if (aIsPromise && bIsPromise) {
+ return a === b;
+ }
+ let length = aStack.length;
+ while (length--) {
+ if (aStack[length] == a) {
+ return bStack[length] == b;
+ }
+ }
+ aStack.push(a);
+ bStack.push(b);
+ let size = 0;
+
+ // 都是数组
+ if(aClassName == '[object Array]') {
+ const aLength = a.length;
+ const bLength = b.length;
+ if (aLength !== bLength) {
+ // 数组长度不同,不是同一个对象
+ return false;
+ }
+ for (let i = 0; i < aLength || i < bLength; i++) {
+ // 递归每一个元素是否相同
+ result = eq(i < aLength ? a[i] : void 0, i < bLength ? b[i] : void 0, aStack, bStack) && result;
+ }
+ if (!result) {
+ return false;
+ }
+ } else if(DeepTypeUtils.isMap(a) && DeepTypeUtils.isMap(b)) {
+ if (a.size != b.size) {
+ return false;
+ }
+ const keysA = [];
+ const keysB = [];
+ a.forEach(function(valueA, keyA) {
+ keysA.push(keyA);
+ });
+ b.forEach(function(valueB, keyB) {
+ keysB.push(keyB);
+ });
+ const mapKeys = [keysA, keysB];
+ const cmpKeys = [keysB, keysA];
+ for (let i = 0; result && i < mapKeys.length; i++) {
+ const mapIter = mapKeys[i];
+ const cmpIter = cmpKeys[i];
+
+ for (let j = 0; result && j < mapIter.length; j++) {
+ const mapKey = mapIter[j];
+ const cmpKey = cmpIter[j];
+ const mapValueA = a.get(mapKey);
+ let mapValueB;
+ if (
+ DeepTypeUtils.isAsymmetricEqualityTester_(mapKey) ||
+ (DeepTypeUtils.isAsymmetricEqualityTester_(cmpKey) &&
+ eq(mapKey, cmpKey))
+ ) {
+ mapValueB = b.get(cmpKey);
+ } else {
+ mapValueB = b.get(mapKey);
+ }
+ result = eq(mapValueA, mapValueB, aStack, bStack);
+ }
+ }
+ if (!result) {
+ return false;
+ }
+ } else if(DeepTypeUtils.isSet(a) && DeepTypeUtils.isSet(b)) {
+ if (a.size != b.size) {
+ return false;
+ }
+ const valuesA = [];
+ a.forEach(function(valueA) {
+ valuesA.push(valueA);
+ });
+ const valuesB = [];
+ b.forEach(function(valueB) {
+ valuesB.push(valueB);
+ });
+ const setPairs = [[valuesA, valuesB], [valuesB, valuesA]];
+ const stackPairs = [[aStack, bStack], [bStack, aStack]];
+ for (let i = 0; result && i < setPairs.length; i++) {
+ const baseValues = setPairs[i][0];
+ const otherValues = setPairs[i][1];
+ const baseStack = stackPairs[i][0];
+ const otherStack = stackPairs[i][1];
+ for (const baseValue of baseValues) {
+ let found = false;
+ for (let j = 0; !found && j < otherValues.length; j++) {
+ const otherValue = otherValues[j];
+ const prevStackSize = baseStack.length;
+ // 深度比较对象
+ found = eq(baseValue, otherValue, baseStack, otherStack);
+ if (!found && prevStackSize !== baseStack.length) {
+ baseStack.splice(prevStackSize);
+ otherStack.splice(prevStackSize);
+ }
+ }
+ result = result && found;
+ }
+ }
+ if (!result) {
+ return false;
+ }
+ } else {
+ const aCtor = a.constructor,
+ bCtor = b.constructor;
+ if (
+ aCtor !== bCtor &&
+ DeepTypeUtils.isFunction_(aCtor) &&
+ DeepTypeUtils.isFunction_(bCtor) &&
+ a instanceof aCtor &&
+ b instanceof bCtor &&
+ !(aCtor instanceof aCtor && bCtor instanceof bCtor)
+ ) {
+ return false;
+ }
+ }
+
+ // 获取对象所有的属性集合
+ const aKeys = DeepTypeUtils.keys(a, aClassName == '[object Array]');
+ size = aKeys.length;
+
+ // 俩个对象属性长度不一致, 俩对象不相同
+ if (DeepTypeUtils.keys(b, bClassName == '[object Array]').length !== size) {
+ return false;
+ }
+
+ // 俩对象属性数量相同, 递归比较每个属性值得值
+ for (const key of aKeys) {
+ console.log('key is:' + key);
+ // b 没有 key 属性
+ if(!DeepTypeUtils.has(b, key)) {
+ result = false;
+ continue;
+ }
+ if (!eq(a[key], b[key], aStack, bStack)) {
+ result = false;
+ }
+ }
+ if (!result) {
+ return false;
+ }
+ aStack.pop();
+ bStack.pop();
+ return result;
+}
+
+function asymmetricMatch_(a, b) {
+ const asymmetricA = DeepTypeUtils.isAsymmetricEqualityTester_(a);
+ const asymmetricB = DeepTypeUtils.isAsymmetricEqualityTester_(b);
+
+ if (asymmetricA === asymmetricB) {
+ return undefined;
+ }
+
+}
+
+/**
+ * 获取对象的自有属性
+ *
+ * @param obj 对象
+ * @param isArray 是否是一个数组
+ */
+function keys(obj, isArray) {
+ const keys = [];
+
+}
+
+export default assertDeepEquals;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/isPromiseLike.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/isPromiseLike.js
new file mode 100644
index 0000000000000000000000000000000000000000..015ab19a2a0c4872d7cb490b61f8e1dd6a8ac90b
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/assert/isPromiseLike.js
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function isPromiseLike(obj) {
+ return !!obj && isFunction_(obj.then);
+}
+
+function isFunction_(value) {
+ return isA_('Function', value);
+}
+
+function isA_(typeName, value) {
+ return getType_(value) === '[object ' + typeName + ']';
+}
+
+function getType_(value) {
+ return Object.prototype.toString.apply(value);
+}
+
+export default isPromiseLike;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/config/DataDriver.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/config/DataDriver.js
new file mode 100644
index 0000000000000000000000000000000000000000..639dffc9cdb912f1f33a6ccb61868c9ed7c695bf
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/config/DataDriver.js
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const SUITES_KEY = 'suites';
+const SPECS_KEY = 'items';
+const DESCRIBE_KEY = 'describe';
+const IT_KEY = 'it';
+const PARAMS_KEY = 'params';
+const STRESS_KEY = 'stress';
+
+class ObjectUtils {
+ static get(object, name, defaultValue) {
+ let result = defaultValue;
+ for (const key in object) {
+ if (key === name) {
+ return object[key];
+ }
+ }
+ return result;
+ }
+
+ static has(object, key) {
+ return Object.prototype.hasOwnProperty.call(object, key);
+ }
+}
+
+class DataDriver {
+ constructor(attr) {
+ this.id = 'dataDriver';
+ this.data = attr.data || {};
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ this.suiteService = this.coreContext.getDefaultService('suite');
+ this.specService = this.coreContext.getDefaultService('spec');
+ }
+
+ getSpecParams() {
+ let specParams = [];
+ let suiteDesc = this.suiteService.getCurrentRunningSuite().description;
+ let specDesc = this.specService.getCurrentRunningSpec().description;
+ let suites = ObjectUtils.get(this.data, SUITES_KEY, []);
+ for (const suiteItem of suites) {
+ let describeValue = ObjectUtils.get(suiteItem, DESCRIBE_KEY, '');
+ if (ObjectUtils.has(suiteItem, DESCRIBE_KEY) && (typeof describeValue === 'object') && describeValue.constructor === Array && describeValue.includes(suiteDesc)) {
+ let specs = ObjectUtils.get(suiteItem, SPECS_KEY, []);
+ for (const specItem of specs) {
+ if (ObjectUtils.has(specItem, IT_KEY) && ObjectUtils.get(specItem, IT_KEY) === specDesc) {
+ return ObjectUtils.get(specItem, PARAMS_KEY, specParams);
+ }
+ }
+ }
+ }
+ return specParams;
+ }
+
+ getSuiteParams() {
+ let suiteParams = {};
+ let suiteDesc = this.suiteService.getCurrentRunningSuite().description;
+ let suites = ObjectUtils.get(this.data, SUITES_KEY, []);
+ for (const suiteItem of suites) {
+ let describeValue = ObjectUtils.get(suiteItem, DESCRIBE_KEY, []);
+ if (ObjectUtils.has(suiteItem, DESCRIBE_KEY) && (typeof describeValue === 'object') && describeValue.constructor === Array && describeValue.includes(suiteDesc)) {
+ suiteParams = Object.assign({}, suiteParams, ObjectUtils.get(suiteItem, PARAMS_KEY, suiteParams));
+ }
+ }
+ return suiteParams;
+ }
+
+ getSpecStress(specDesc) {
+ let stress = 1;
+ let suiteDesc = this.suiteService.getCurrentRunningSuite().description;
+ let suites = ObjectUtils.get(this.data, SUITES_KEY, []);
+ for (const suiteItem of suites) {
+ let describeValue = ObjectUtils.get(suiteItem, DESCRIBE_KEY, '');
+ if (ObjectUtils.has(suiteItem, DESCRIBE_KEY) && (typeof describeValue === 'object') && describeValue.constructor === Array && describeValue.includes(suiteDesc)) {
+ let specs = ObjectUtils.get(suiteItem, SPECS_KEY, []);
+ for (const specItem of specs) {
+ if (ObjectUtils.has(specItem, IT_KEY) && ObjectUtils.get(specItem, IT_KEY) === specDesc) {
+ let tempStress = ObjectUtils.get(specItem, STRESS_KEY, stress);
+ return (Number.isInteger(tempStress) && tempStress >= 1) ? tempStress : stress;
+ }
+ }
+ }
+ }
+ return stress;
+ }
+
+ getSuiteStress(suiteDesc) {
+ let stress = 1;
+ let suites = ObjectUtils.get(this.data, SUITES_KEY, []);
+ for (const suiteItem of suites) {
+ let describeValue = ObjectUtils.get(suiteItem, DESCRIBE_KEY, []);
+ if (ObjectUtils.has(suiteItem, DESCRIBE_KEY) && (typeof describeValue === 'object') && describeValue.constructor === Array && describeValue.includes(suiteDesc)) {
+ let tempStress = ObjectUtils.get(suiteItem, STRESS_KEY, stress);
+ return (Number.isInteger(tempStress) && tempStress >= 1) ? tempStress : stress;
+ }
+ }
+ return stress;
+ }
+}
+
+export default DataDriver;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/config/Filter.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/config/Filter.js
new file mode 100644
index 0000000000000000000000000000000000000000..0ca3b4f412353ad0e9fa70bcfe775c905b5e02a9
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/config/Filter.js
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class ClassFilter {
+ constructor(suiteName, itName, params) {
+ this.suiteName = suiteName;
+ this.itName = itName;
+ this.params = params;
+ }
+
+ filterSuite() {
+ return !this.params.split(',').map(item => item.split('#')[0]).map(item => item == this.suiteName).reduce((pre, cur) => pre || cur, false);
+ }
+
+ filterIt() {
+ let classArray = this.params.split(',') || [];
+ let suiteFilterResult = classArray.filter(item => !item.includes('#')).map(item => item == this.suiteName).reduce((pre, cur) => pre || cur, false);
+ let itFilterResult = classArray.filter(item => item.includes('#')).map(item => item == (this.suiteName + '#' + this.itName)).reduce((pre, cur) => pre || cur, false);
+ return !(suiteFilterResult || itFilterResult);
+ }
+}
+
+class NotClassFilter {
+ constructor(suiteName, itName, params) {
+ this.suiteName = suiteName;
+ this.itName = itName;
+ this.params = params;
+ }
+
+ filterSuite() {
+ return this.params.split(',').map(item => item == this.suiteName).reduce((pre, cur) => pre || cur, false);
+ }
+
+ filterIt() {
+ return this.params.split(',').some(item => item == (this.suiteName + '#' + this.itName));
+ }
+}
+
+class SuiteAndItNameFilter {
+ constructor(suiteName, itName, params) {
+ this.suiteName = suiteName;
+ this.itName = itName;
+ this.params = params;
+ }
+
+ filterSuite() {
+ return !this.params.split(',').map(item => item == this.suiteName).reduce((pre, cur) => pre || cur, false);
+ }
+
+ filterIt() {
+ return !this.params.split(',').map(item => item == this.itName).reduce((pre, cur) => pre || cur, false);
+ }
+}
+
+
+class TestTypesFilter {
+ constructor(suiteName, itName, fi, params) {
+ this.suiteName = suiteName;
+ this.itName = itName;
+ this.params = params;
+ this.fi = fi;
+ }
+
+ filterIt() {
+ return !((this.params === (this.fi & this.params)) || this.fi === 0);
+ }
+}
+
+export {ClassFilter, NotClassFilter, SuiteAndItNameFilter, TestTypesFilter};
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/config/configService.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/config/configService.js
new file mode 100644
index 0000000000000000000000000000000000000000..94f4a764b04d1d190e495a53ed09834f2e411bf2
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/config/configService.js
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {ClassFilter, NotClassFilter, SuiteAndItNameFilter, TestTypesFilter} from './Filter';
+import {TAG} from '../../Constant';
+const STRESS_RULE = /^[1-9]\d*$/;
+
+class ConfigService {
+ constructor(attr) {
+ this.id = attr.id;
+ this.supportAsync = false;
+ this.random = false;
+ this.filterValid = [];
+ this.filter = 0;
+ this.flag = false;
+ this.suite = null;
+ this.itName = null;
+ this.testType = null;
+ this.level = null;
+ this.size = null;
+ this.class = null;
+ this.notClass = null;
+ this.timeout = null;
+ // 遇错即停模式配置
+ this.breakOnError = false;
+ // 压力测试配置
+ this.stress = null;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ }
+
+ isNormalInteger(str) {
+ const n = Math.floor(Number(str));
+ return n !== Infinity && String(n) === String(str) && n >= 0;
+ }
+
+ getStress() {
+ if (this.stress === undefined || this.stress === '' || this.stress === null) {
+ return 1;
+ }
+ return !this.stress.match(STRESS_RULE) ? 1 : Number.parseInt(this.stress);
+ }
+
+ basicParamValidCheck(params) {
+ let size = params.size;
+ if (size !== undefined && size !== '' && size !== null) {
+ let sizeArray = ['small', 'medium', 'large'];
+ if (sizeArray.indexOf(size) === -1) {
+ this.filterValid.push('size:' + size);
+ }
+ }
+ let level = params.level;
+ if (level !== undefined && level !== '' && level !== null) {
+ let levelArray = ['0', '1', '2', '3', '4'];
+ if (levelArray.indexOf(level) === -1) {
+ this.filterValid.push('level:' + level);
+ }
+ }
+ let testType = params.testType;
+ if (testType !== undefined && testType !== '' && testType !== null) {
+ let testTypeArray = ['function', 'performance', 'power', 'reliability', 'security',
+ 'global', 'compatibility', 'user', 'standard', 'safety', 'resilience'];
+ if (testTypeArray.indexOf(testType) === -1) {
+ this.filterValid.push('testType:' + testType);
+ }
+ }
+ }
+
+ filterParamValidCheck(params) {
+ let timeout = params.timeout;
+ if (timeout !== undefined && timeout !== '' && timeout !== null) {
+ if (!this.isNormalInteger(timeout)) {
+ this.filterValid.push('timeout:' + timeout);
+ }
+ }
+
+ let paramKeys = ['dryRun', 'random', 'breakOnError', 'coverage'];
+ for (const key of paramKeys) {
+ if (params[key] !== undefined && params[key] !== 'true' && params[key] !== 'false') {
+ this.filterValid.push(`${key}:${params[key]}`);
+ }
+ }
+
+ // 压力测试参数验证,正整数
+ if (params.stress !== undefined && params.stress !== '' && params.stress !== null) {
+ if (!params.stress.match(STRESS_RULE)) {
+ this.filterValid.push('stress:' + params.stress);
+ }
+ }
+
+ let nameRule = /^[A-Za-z]{1}[\w#,.]*$/;
+ let paramClassKeys = ['class', 'notClass'];
+ for (const key of paramClassKeys) {
+ if (params[key] !== undefined && params[key] !== '' && params[key] !== null) {
+ let classArray = params[key].split(',');
+ classArray.forEach(item => !item.match(nameRule) ? this.filterValid.push(`${key}:${params[key]}`) : null);
+ }
+ }
+ }
+
+ setConfig(params) {
+ this.basicParamValidCheck(params);
+ this.filterParamValidCheck(params);
+ try {
+ this.class = params.class;
+ this.notClass = params.notClass;
+ this.flag = params.flag || {flag: false};
+ this.suite = params.suite;
+ this.itName = params.itName;
+ this.filter = params.filter;
+ this.testType = params.testType;
+ this.level = params.level;
+ this.size = params.size;
+ this.timeout = params.timeout;
+ this.dryRun = params.dryRun;
+ this.breakOnError = params.breakOnError;
+ this.random = params.random === 'true' ? true : false;
+ this.stress = params.stress;
+ this.coverage = params.coverage;
+ this.filterParam = {
+ testType: {
+ 'function': 1,
+ 'performance': 1 << 1,
+ 'power': 1 << 2,
+ 'reliability': 1 << 3,
+ 'security': 1 << 4,
+ 'global': 1 << 5,
+ 'compatibility': 1 << 6,
+ 'user': 1 << 7,
+ 'standard': 1 << 8,
+ 'safety': 1 << 9,
+ 'resilience': 1 << 10,
+ },
+ level: {
+ '0': 1 << 24,
+ '1': 1 << 25,
+ '2': 1 << 26,
+ '3': 1 << 27,
+ '4': 1 << 28,
+ },
+ size: {
+ 'small': 1 << 16,
+ 'medium': 1 << 17,
+ 'large': 1 << 18,
+ }
+ };
+ this.parseParams();
+ } catch (err) {
+ console.info(`${TAG}setConfig error: ${err.message}`);
+ }
+ }
+
+ parseParams() {
+ if (this.filter != null) {
+ return;
+ }
+ let testTypeFilter = 0;
+ let sizeFilter = 0;
+ let levelFilter = 0;
+ if (this.testType != null) {
+ testTypeFilter = this.testType.split(',')
+ .map(item => this.filterParam.testType[item] || 0)
+ .reduce((pre, cur) => pre | cur, 0);
+ }
+ if (this.level != null) {
+ levelFilter = this.level.split(',')
+ .map(item => this.filterParam.level[item] || 0)
+ .reduce((pre, cur) => pre | cur, 0);
+ }
+ if (this.size != null) {
+ sizeFilter = this.size.split(',')
+ .map(item => this.filterParam.size[item] || 0)
+ .reduce((pre, cur) => pre | cur, 0);
+ }
+ this.filter = testTypeFilter | sizeFilter | levelFilter;
+ console.info(`${TAG}filter params:${this.filter}`);
+ }
+
+ isCurrentSuite(description) {
+ if (this.suite !== undefined && this.suite !== '' && this.suite !== null) {
+ let suiteArray = this.suite.split(',');
+ return suiteArray.indexOf(description) !== -1;
+ }
+ return false;
+ }
+
+ filterSuite(currentSuiteName) {
+ let filterArray = [];
+ if (this.suite !== undefined && this.suite !== '' && this.suite !== null) {
+ filterArray.push(new SuiteAndItNameFilter(currentSuiteName, '', this.suite));
+ }
+ if (this.class !== undefined && this.class !== '' && this.class !== null) {
+ filterArray.push(new ClassFilter(currentSuiteName, '', this.class));
+ }
+ if (this.notClass !== undefined && this.notClass !== '' && this.notClass !== null) {
+ filterArray.push(new NotClassFilter(currentSuiteName, '', this.notClass));
+ }
+
+ let result = filterArray.map(item => item.filterSuite()).reduce((pre, cur) => pre || cur, false);
+ return result;
+ }
+
+ filterDesc(currentSuiteName, desc, fi, coreContext) {
+ let filterArray = [];
+ if (this.itName !== undefined && this.itName !== '' && this.itName !== null) {
+ filterArray.push(new SuiteAndItNameFilter(currentSuiteName, desc, this.itName));
+ }
+ if (this.class !== undefined && this.class !== '' && this.class !== null) {
+ filterArray.push(new ClassFilter(currentSuiteName, desc, this.class));
+ }
+ if (this.notClass !== undefined && this.notClass !== '' && this.notClass !== null) {
+ filterArray.push(new NotClassFilter(currentSuiteName, desc, this.notClass));
+ }
+ if (typeof (this.filter) !== 'undefined' && this.filter !== 0 && fi !== 0) {
+ filterArray.push(new TestTypesFilter('', '', fi, this.filter));
+ }
+ let result = filterArray.map(item => item.filterIt()).reduce((pre, cur) => pre || cur, false);
+ return result;
+ }
+
+ isRandom() {
+ return this.random || false;
+ }
+
+ isBreakOnError() {
+ return this.breakOnError !== true ? false : true;
+ }
+
+ setSupportAsync(value) {
+ this.supportAsync = value;
+ }
+
+ isSupportAsync() {
+ return this.supportAsync;
+ }
+
+ translateParams(parameters) {
+ const keySet = new Set([
+ '-s class', '-s notClass', '-s suite', '-s itName',
+ '-s level', '-s testType', '-s size', '-s timeout',
+ '-s dryRun', '-s random', '-s breakOnError', '-s stress',
+ '-s coverage', 'class', 'notClass', 'suite', 'itName',
+ 'level', 'testType', 'size', 'timeout', 'dryRun', 'random',
+ 'breakOnError', 'stress', 'coverage'
+ ]);
+ let targetParams = {};
+ for (const key in parameters) {
+ if (keySet.has(key)) {
+ var newKey = key.replace("-s ", "");
+ targetParams[newKey] = parameters[key];
+ }
+ }
+ return targetParams;
+ }
+ translateParamsToString(parameters) {
+ const keySet = new Set([
+ '-s class', '-s notClass', '-s suite', '-s itName',
+ '-s level', '-s testType', '-s size', '-s timeout',
+ '-s dryRun', '-s random', '-s breakOnError', '-s stress',
+ '-s coverage', 'class', 'notClass', 'suite', 'itName',
+ 'level', 'testType', 'size', 'timeout', 'dryRun', 'random',
+ 'breakOnError', 'stress', 'coverage'
+ ]);
+ let targetParams = '';
+ for (const key in parameters) {
+ if (keySet.has(key)) {
+ targetParams += ' ' + key + ' ' + parameters[key];
+ }
+ }
+ return targetParams.trim();
+ }
+
+ execute() {
+ }
+}
+
+export {
+ ConfigService
+};
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/coverage/coverageCollect.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/coverage/coverageCollect.js
new file mode 100644
index 0000000000000000000000000000000000000000..632a6820503dcdec7646add5ee6a2c6b3c6227bb
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/coverage/coverageCollect.js
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import SysTestKit from "../kit/SysTestKit";
+
+export async function collectCoverageData() {
+ if (globalThis.__coverage__ === undefined) {
+ return;
+ }
+ const strJson = JSON.stringify(globalThis.__coverage__);
+ const strLen = strJson.length;
+ const maxLen = 500;
+ const maxCount = Math.floor(strLen / maxLen);
+ const OHOS_REPORT_COVERAGE_DATA = 'OHOS_REPORT_COVERAGE_DATA:';
+ for (let count = 0; count <= maxCount; count++) {
+ console.info(`${OHOS_REPORT_COVERAGE_DATA} ${strJson.substring(count * maxLen, (count + 1) * maxLen)}`);
+ await SysTestKit.print(`${OHOS_REPORT_COVERAGE_DATA} ${strJson.substring(count * maxLen, (count + 1) * maxLen)}`);
+ }
+}
\ No newline at end of file
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/kit/SysTestKit.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/kit/SysTestKit.js
new file mode 100644
index 0000000000000000000000000000000000000000..65d063c7d56a85f64967103922a6b261bd79c0b8
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/kit/SysTestKit.js
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {TAG} from '../../Constant';
+
+export default class SysTestKit {
+
+ static delegator = null;
+ static systemTime = null;
+
+ constructor() {
+ this.id = 'sysTestKit';
+ this.index = 0;
+ }
+
+ static actionStart(tag) {
+ console.info(`${TAG}${JSON.stringify(tag)}`);
+ var message = '\n' + 'OHOS_REPORT_ACTIONSTART: ' + JSON.stringify(tag) + '\n';
+ SysTestKit.print(message);
+ console.info(`${TAG}${JSON.stringify(tag)} actionStart print success`);
+ }
+
+ static actionEnd(tag) {
+ console.info(`${TAG}${JSON.stringify(tag)}`);
+ var message = '\n' + 'OHOS_REPORT_ACTIONEND: ' + JSON.stringify(tag) + '\n';
+ SysTestKit.print(message);
+ console.info(`${TAG}${JSON.stringify(tag)} actionEnd print success`);
+ }
+
+ static async existKeyword(keyword, timeout) {
+ let reg = new RegExp(/^[a-zA-Z0-9]{1,}$/);
+ if (!reg.test(keyword)) {
+ throw new Error('keyword must contain more than one string, and only letters and numbers are supported.');
+ }
+ timeout = timeout || 4;
+
+ let searchResult = false;
+ let cmd = 'hilog -x | grep -i \'' + keyword + '\' | wc -l';
+ await executePromise(cmd, timeout).then((data) => {
+ searchResult = data;
+ });
+ return searchResult;
+ }
+ static async print(message) {
+ if ('printSync' in SysTestKit.delegator) {
+ console.debug(`${TAG}printSync called ...`);
+ SysTestKit.delegator.printSync(message);
+ } else {
+ await SysTestKit.delegator.print(message);
+ }
+ }
+
+ static async getRealTime() {
+ let currentTime = new Date().getTime();
+ if (SysTestKit.systemTime !== null && SysTestKit.systemTime !== undefined) {
+ await SysTestKit.systemTime.getRealTime().then((time) => {
+ console.info(`${TAG}systemTime.getRealTime success data: ${JSON.stringify(time)}`);
+ currentTime = time;
+ }).catch((error) => {
+ console.error(`${TAG}failed to systemTime.getRealTime because ${JSON.stringify(error)}`);
+ });
+ }
+ return currentTime;
+ }
+}
+
+function executePromise(cmd, timeout) {
+ return new Promise((resolve, reject) => {
+ SysTestKit.delegator.executeShellCommand(cmd, timeout,
+ (error, data) => {
+ console.info(`${TAG}existKeyword CallBack: err : ${JSON.stringify(error)}`);
+ console.info(`${TAG}existKeyword CallBack: data : ${JSON.stringify(data)}`);
+ resolve(parseInt(data.stdResult) > 3 ? true : false);
+ });
+ });
+}
\ No newline at end of file
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/mock/ArgumentMatchers.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/mock/ArgumentMatchers.js
new file mode 100644
index 0000000000000000000000000000000000000000..6a9d7aac464e95383ea31385284b6603c34e084c
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/mock/ArgumentMatchers.js
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class ArgumentMatchers {
+ ANY = "";
+ ANY_STRING = "";
+ ANY_BOOLEAN = "";
+ ANY_NUMBER = "";
+ ANY_OBJECT = "";
+ ANY_FUNCTION = "";
+ MATCH_REGEXS = "";
+
+ static any() {
+ }
+
+ static anyString() {
+ }
+
+ static anyBoolean() {
+ }
+
+ static anyNumber() {
+ }
+
+ static anyObj() {
+ }
+
+ static anyFunction() {
+ }
+
+ static matchRegexs() {
+ let regex = arguments[0];
+ if (ArgumentMatchers.isRegExp(regex)) {
+ return regex;
+ }
+ throw Error("not a regex");
+ }
+
+ static isRegExp(value) {
+ return Object.prototype.toString.call(value) === "[object RegExp]";
+ }
+
+ matcheReturnKey() {
+ let arg = arguments[0];
+ let regex = arguments[1];
+ let stubSetKey = arguments[2];
+
+ if (stubSetKey && stubSetKey == this.ANY) {
+ return this.ANY;
+ }
+
+ if (typeof arg === "string" && !regex) {
+ return this.ANY_STRING;
+ }
+
+ if (typeof arg === "boolean" && !regex) {
+ return this.ANY_BOOLEAN;
+ }
+
+ if (typeof arg === "number" && !regex) {
+ return this.ANY_NUMBER;
+ }
+
+ if (typeof arg === "object" && !regex) {
+ return this.ANY_OBJECT;
+ }
+
+ if (typeof arg === "function" && !regex) {
+ return this.ANY_FUNCTION;
+ }
+
+ if (typeof arg === "string" && regex) {
+ return regex.test(arg);
+ }
+
+ return null;
+ }
+
+ matcheStubKey() {
+ let key = arguments[0];
+
+ if (key === ArgumentMatchers.any) {
+ return this.ANY;
+ }
+
+ if (key === ArgumentMatchers.anyString) {
+ return this.ANY_STRING;
+ }
+ if (key === ArgumentMatchers.anyBoolean) {
+ return this.ANY_BOOLEAN;
+ }
+ if (key === ArgumentMatchers.anyNumber) {
+ return this.ANY_NUMBER;
+ }
+ if (key === ArgumentMatchers.anyObj) {
+ return this.ANY_OBJECT;
+ }
+ if (key === ArgumentMatchers.anyFunction) {
+ return this.ANY_FUNCTION;
+ }
+
+ if (ArgumentMatchers.isRegExp(key)) {
+ return key;
+ }
+
+ return null;
+ }
+}
+
+export default ArgumentMatchers;
\ No newline at end of file
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/mock/ExtendInterface.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/mock/ExtendInterface.js
new file mode 100644
index 0000000000000000000000000000000000000000..c6a866a6df662ad10a7f6869dcbc2381fa47bcdc
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/mock/ExtendInterface.js
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class ExtendInterface {
+ constructor(mocker) {
+ this.mocker = mocker;
+ }
+
+ stub() {
+ this.params = arguments;
+ return this;
+ }
+
+ stubMockedCall(returnInfo) {
+ this.mocker.stubApply(this, this.params, returnInfo);
+ }
+
+ afterReturn(value) {
+ this.stubMockedCall(function () {
+ return value;
+ });
+ }
+
+ afterReturnNothing() {
+ this.stubMockedCall(function () {
+ return undefined;
+ });
+ }
+
+ afterAction(action) {
+ this.stubMockedCall(action);
+ }
+
+ afterThrow(msg) {
+ this.stubMockedCall(function () {
+ throw msg;
+ });
+ }
+
+ clear() {
+ this.mocker.clear();
+ }
+}
+
+export default ExtendInterface;
\ No newline at end of file
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/mock/MockKit.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/mock/MockKit.js
new file mode 100644
index 0000000000000000000000000000000000000000..1bd83be8a3eb8435486013fe1be5947e0fbe574e
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/mock/MockKit.js
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import ExtendInterface from "./ExtendInterface";
+import VerificationMode from "./VerificationMode";
+import ArgumentMatchers from "./ArgumentMatchers";
+
+class MockKit {
+
+ constructor() {
+ this.mFunctions = [];
+ this.stubs = new Map();
+ this.recordCalls = new Map();
+ this.currentSetKey = new Map();
+ this.mockObj = null;
+ this.recordMockedMethod = new Map();
+ }
+
+ init() {
+ this.reset();
+ }
+
+ reset() {
+ this.mFunctions = [];
+ this.stubs = {};
+ this.recordCalls = {};
+ this.currentSetKey = new Map();
+ this.mockObj = null;
+ this.recordMockedMethod = new Map();
+ }
+
+ clearAll() {
+ this.reset();
+ var props = Object.keys(this);
+ for (var i = 0; i < props.length; i++) {
+ delete this[props[i]];
+ }
+
+ var props = Object.getOwnPropertyNames(this);
+ for (var i = 0; i < props.length; i++) {
+ delete this[props[i]];
+ }
+ for (var key in this) {
+ delete this[key];
+ }
+ }
+
+ clear(obj) {
+ if (!obj) throw Error("Please enter an object to be cleaned");
+ if (typeof (obj) != 'object') throw new Error('Not a object');
+ this.recordMockedMethod.forEach(function (value, key, map) {
+ if (key) {
+ obj[key] = value;
+ }
+ });
+ }
+
+ ignoreMock(obj, method) {
+ if (typeof (obj) != 'object') throw new Error('Not a object');
+ if (typeof (method) != 'function') throw new Error('Not a function');
+ let og = this.recordMockedMethod.get(method.propName);
+ if (og) {
+ obj[method.propName] = og;
+ this.recordMockedMethod.set(method.propName, undefined);
+ }
+ }
+
+ extend(dest, source) {
+ dest["stub"] = source["stub"];
+ dest["afterReturn"] = source["afterReturn"];
+ dest["afterReturnNothing"] = source["afterReturnNothing"];
+ dest["afterAction"] = source["afterAction"];
+ dest["afterThrow"] = source["afterThrow"];
+ dest["stubMockedCall"] = source["stubMockedCall"];
+ dest["clear"] = source["clear"];
+ return dest;
+ }
+
+ stubApply(f, params, returnInfo) {
+ let values = this.stubs.get(f);
+ if (!values) {
+ values = new Map();
+ }
+ let key = params[0];
+ if (typeof key == "undefined") {
+ key = "anonymous-mock-" + f.propName;
+ }
+ let matcher = new ArgumentMatchers();
+ if (matcher.matcheStubKey(key)) {
+ key = matcher.matcheStubKey(key);
+ if (key) {
+ this.currentSetKey.set(f, key);
+ }
+ }
+ values.set(key, returnInfo);
+ this.stubs.set(f, values);
+ }
+
+ getReturnInfo(f, params) {
+ let values = this.stubs.get(f);
+ if (!values) {
+ return undefined;
+ }
+ let retrunKet = params[0];
+ if (typeof retrunKet == "undefined") {
+ retrunKet = "anonymous-mock-" + f.propName;
+ }
+ let stubSetKey = this.currentSetKey.get(f);
+
+ if (stubSetKey && (typeof (retrunKet) != "undefined")) {
+ retrunKet = stubSetKey;
+ }
+ let matcher = new ArgumentMatchers();
+ if (matcher.matcheReturnKey(params[0], undefined, stubSetKey) && matcher.matcheReturnKey(params[0], undefined, stubSetKey) != stubSetKey) {
+ retrunKet = params[0];
+ }
+
+ values.forEach(function (value, key, map) {
+ if (ArgumentMatchers.isRegExp(key) && matcher.matcheReturnKey(params[0], key)) {
+ retrunKet = key;
+ }
+ });
+
+ return values.get(retrunKet);
+ }
+
+ findName(obj, value) {
+ let properties = this.findProperties(obj);
+ let name = null;
+ properties.filter(item => (item !== 'caller' && item !== 'arguments')).forEach(
+ function (va1, idx, array) {
+ if (obj[va1] === value) {
+ name = va1;
+ }
+ }
+ );
+ return name;
+ }
+
+ isFunctionFromPrototype(f, container, propName) {
+ if (container.constructor != Object && container.constructor.prototype !== container) {
+ return container.constructor.prototype[propName] === f;
+ }
+ return false;
+ }
+
+ findProperties(obj, ...arg) {
+ function getProperty(new_obj) {
+ if (new_obj.__proto__ === null) {
+ return [];
+ }
+ let properties = Object.getOwnPropertyNames(new_obj);
+ return [...properties, ...getProperty(new_obj.__proto__)];
+ }
+ return getProperty(obj);
+ }
+
+ recordMethodCall(originalMethod, args) {
+ Function.prototype.getName = function () {
+ return this.name || this.toString().match(/function\s*([^(]*)\(/)[1];
+ };
+ let name = originalMethod.getName();
+ let arglistString = name + '(' + Array.from(args).toString() + ')';
+ let records = this.recordCalls.get(arglistString);
+ if (!records) {
+ records = 0;
+ }
+ records++;
+ this.recordCalls.set(arglistString, records);
+ }
+
+ mockFunc(originalObject, originalMethod) {
+ let tmp = this;
+ this.originalMethod = originalMethod;
+ let f = function () {
+ let args = arguments;
+ let action = tmp.getReturnInfo(f, args);
+ if (originalMethod) {
+ tmp.recordMethodCall(originalMethod, args);
+ }
+ if (action) {
+ return action.apply(this, args);
+ }
+ };
+
+ f.container = null || originalObject;
+ f.original = originalMethod || null;
+
+ if (originalObject && originalMethod) {
+ if (typeof (originalMethod) != 'function') throw new Error('Not a function');
+ var name = this.findName(originalObject, originalMethod);
+ originalObject[name] = f;
+ this.recordMockedMethod.set(name, originalMethod);
+ f.propName = name;
+ f.originalFromPrototype = this.isFunctionFromPrototype(f.original, originalObject, f.propName);
+ }
+ f.mocker = this;
+ this.mFunctions.push(f);
+ this.extend(f, new ExtendInterface(this));
+ return f;
+ }
+
+ verify(methodName, argsArray) {
+ if (!methodName) {
+ throw Error("not a function name");
+ }
+ let a = this.recordCalls.get(methodName + '(' + argsArray.toString() + ')');
+ return new VerificationMode(a ? a : 0);
+ }
+
+ mockObject(object) {
+ if (!object || typeof object === "string") {
+ throw Error(`this ${object} cannot be mocked`);
+ }
+ const _this = this;
+ let mockedObject = {};
+ let keys = Reflect.ownKeys(object);
+ keys.filter(key => (typeof Reflect.get(object, key)) === 'function')
+ .forEach(key => {
+ mockedObject[key] = object[key];
+ mockedObject[key] = _this.mockFunc(mockedObject, mockedObject[key]);
+ });
+ return mockedObject;
+ }
+}
+
+function ifMockedFunction(f) {
+ if (Object.prototype.toString.call(f) != "[object Function]" &&
+ Object.prototype.toString.call(f) != "[object AsyncFunction]") {
+ throw Error("not a function");
+ }
+ if (!f.stub) {
+ throw Error("not a mock function");
+ }
+ return true;
+}
+
+function when(f) {
+ if (ifMockedFunction(f)) {
+ return f.stub.bind(f);
+ }
+}
+
+export {MockKit, when};
\ No newline at end of file
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/mock/VerificationMode.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/mock/VerificationMode.js
new file mode 100644
index 0000000000000000000000000000000000000000..28eda2b05fa5ec9f78f9b20d1be1b6c87ffaf33b
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/mock/VerificationMode.js
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {expect} from '../../interface';
+
+class VerificationMode {
+ constructor(times) {
+ this.doTimes = times;
+ }
+
+ times(count) {
+ expect(count).assertEqual(this.doTimes);
+ }
+
+ never() {
+ console.log(this.doTimes);
+ expect(0).assertEqual(this.doTimes);
+ }
+
+ once() {
+ expect(1).assertEqual(this.doTimes);
+ }
+
+ atLeast(count) {
+ if (count > this.doTimes) {
+ throw Error('failed ' + count + ' greater than the actual execution times of method');
+ }
+ }
+
+ atMost(count) {
+ if (count < this.doTimes) {
+ throw Error('failed ' + count + ' less than the actual execution times of method');
+ }
+ }
+}
+
+export default VerificationMode;
\ No newline at end of file
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/report/OhReport.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/report/OhReport.js
new file mode 100644
index 0000000000000000000000000000000000000000..f648b11a9d0fd487cc0cc83b1ed360a788c5d700
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/report/OhReport.js
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import SysTestKit from "../kit/SysTestKit";
+import {collectCoverageData} from '../coverage/coverageCollect';
+import {TAG} from '../../Constant';
+
+class OhReport {
+ constructor(attr) {
+ this.delegator = attr.delegator;
+ this.abilityDelegatorArguments = attr.abilityDelegatorArguments;
+ this.id = 'report';
+ this.index = 0;
+ this.duration = 0;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ this.suiteService = this.coreContext.getDefaultService('suite');
+ this.specService = this.coreContext.getDefaultService('spec');
+ }
+
+ taskStart() {
+ }
+
+ async taskDone() {
+ if (this.abilityDelegatorArguments !== null) {
+ this.taskDoneTime = new Date().getTime();
+ let summary = this.suiteService.getSummary();
+ const configService = this.coreContext.getDefaultService('config');
+ if (configService['coverage'] === 'true') {
+ await collectCoverageData();
+ }
+ let message = '\n' + 'OHOS_REPORT_RESULT: stream=Tests run: ' + summary.total + ', Failure: ' + summary.failure;
+ message += ', Error: ' + summary.error;
+ message += ', Pass: ' + summary.pass;
+ message += ', Ignore: ' + summary.ignore;
+ message += '\n' + 'OHOS_REPORT_CODE: ' + (summary.failure > 0 ? -1 : 0) + '\n';
+ let isHasError = summary.failure > 0 || summary.error > 0;
+ let config = this.coreContext.getDefaultService('config');
+ if (config.isBreakOnError() && isHasError) {
+ // 未执行全部说明
+ message += '\n' + 'OHOS_REPORT_RESULT: breakOnError model, Stopping whole test suite if one specific test case failed or error' + '\n';
+ }
+ message += 'OHOS_REPORT_STATUS: taskconsuming=' + summary.duration + '\n';
+ console.info(`${message}`);
+ await SysTestKit.print(message);
+ }
+ console.info(`${TAG}report print success`);
+ this.delegator.finishTest('your test finished!!!', 0, () => { });
+ }
+
+ incorrectFormat() {
+ if (this.coreContext.getDefaultService('config').filterValid.length !== 0) {
+ var value = this.coreContext.getDefaultService('config').filterValid;
+ var message = 'this param ' + value.join(',') + ' is invalid' + '\n';
+ this.delegator.finishTest(message, 0, () => {
+ });
+ }
+ }
+
+ async suiteStart() {
+ if (this.abilityDelegatorArguments !== null) {
+ let message = '\n' + 'OHOS_REPORT_SUM: ' + this.suiteService.getCurrentRunningSuite().getSpecsNum();
+ message += '\n' + 'OHOS_REPORT_STATUS: class=' + this.suiteService.getCurrentRunningSuite().description + '\n';
+ console.info(`${message}`);
+ await SysTestKit.print(message);
+ console.info(`${TAG}${this.suiteService.getCurrentRunningSuite().description} suiteStart print success`);
+ }
+ }
+
+ async suiteDone() {
+ if (this.abilityDelegatorArguments !== null) {
+ const currentRunningSuite = this.suiteService.getCurrentRunningSuite();
+ let message = '\n' + 'OHOS_REPORT_STATUS: class=' + this.suiteService.getCurrentRunningSuite().description;
+ message += '\n' + 'OHOS_REPORT_STATUS: suiteconsuming=' + this.suiteService.getCurrentRunningSuite().duration;
+ if (currentRunningSuite.hookError) {
+ message += '\n' + `OHOS_REPORT_STATUS: ${currentRunningSuite.hookError.message}`;
+ }
+ message += '\n';
+ console.info(`${message}`);
+ await SysTestKit.print(message);
+ console.info(`${TAG}${this.suiteService.getCurrentRunningSuite().description} suiteDone print success`);
+ }
+ }
+
+ async specStart() {
+ if (this.abilityDelegatorArguments !== null) {
+ let message = '\n' + 'OHOS_REPORT_STATUS: class=' + this.suiteService.getCurrentRunningSuite().description;
+ message += '\n' + 'OHOS_REPORT_STATUS: current=' + (++this.index);
+ message += '\n' + 'OHOS_REPORT_STATUS: id=JS';
+ message += '\n' + 'OHOS_REPORT_STATUS: numtests=' + this.specService.getTestTotal();
+ message += '\n' + 'OHOS_REPORT_STATUS: stream=';
+ message += '\n' + 'OHOS_REPORT_STATUS: test=' + this.specService.currentRunningSpec.description;
+ message += '\n' + 'OHOS_REPORT_STATUS_CODE: 1' + '\n';
+ console.info(`${message}`);
+ await SysTestKit.print(message);
+ console.info(`${TAG}${this.specService.currentRunningSpec.description} specStart start print success`);
+ }
+ }
+
+ async specDone() {
+ if (this.abilityDelegatorArguments !== null) {
+ let message = '\n' + 'OHOS_REPORT_STATUS: class=' + this.suiteService.getCurrentRunningSuite().description;
+ message += '\n' + 'OHOS_REPORT_STATUS: current=' + (this.index);
+ message += '\n' + 'OHOS_REPORT_STATUS: id=JS';
+ message += '\n' + 'OHOS_REPORT_STATUS: numtests=' + this.specService.getTestTotal();
+ let errorMsg = '';
+ if (this.specService.currentRunningSpec.error) {
+ message += '\n' + 'OHOS_REPORT_STATUS: stack=' + this.specService.currentRunningSpec.error.message;
+ message += '\n' + 'OHOS_REPORT_STATUS: stream=';
+ message += '\n' + 'Error in ' + this.specService.currentRunningSpec.description;
+ message += '\n' + this.specService.currentRunningSpec.error.message;
+ message += '\n' + 'OHOS_REPORT_STATUS: test=' + this.specService.currentRunningSpec.description;
+ message += '\n' + 'OHOS_REPORT_STATUS_CODE: -1' + '\n';
+ } else if (this.specService.currentRunningSpec) {
+ if (this.specService.currentRunningSpec.fail) {
+ errorMsg = this.specService.currentRunningSpec.fail?.message;
+ message += '\n' + 'OHOS_REPORT_STATUS: stack=' + errorMsg;
+ message += '\n' + 'OHOS_REPORT_STATUS: stream=';
+ message += '\n' + 'Error in ' + this.specService.currentRunningSpec.description;
+ message += '\n' + errorMsg + '\n' + 'OHOS_REPORT_STATUS: test=' + this.specService.currentRunningSpec.description;
+ message += '\n' + 'OHOS_REPORT_STATUS_CODE: -2' + '\n';
+ } else {
+ message += '\n' + 'OHOS_REPORT_STATUS: stream=';
+ message += '\n' + 'OHOS_REPORT_STATUS: test=' + this.specService.currentRunningSpec.description;
+ message += '\n' + 'OHOS_REPORT_STATUS_CODE: 0' + '\n';
+ }
+ } else {
+ message += '\n';
+ }
+ message += 'OHOS_REPORT_STATUS: consuming=' + this.specService.currentRunningSpec.duration + '\n';
+ console.info(`${message}`);
+ await SysTestKit.print(message);
+ console.info(`${TAG}${this.specService.currentRunningSpec.description} specDone end print success`);
+ }
+ }
+}
+
+export default OhReport;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/report/ReportExtend.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/report/ReportExtend.js
new file mode 100644
index 0000000000000000000000000000000000000000..852fbcd5cbf97e776ebe5177a029df0f516594a5
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/module/report/ReportExtend.js
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class ReportExtend {
+ constructor(fileModule) {
+ this.id = 'extend';
+ this.fileModule = fileModule;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ this.suiteService = this.coreContext.getDefaultService('suite');
+ }
+
+ taskStart() {
+
+ }
+
+ taskDone() {
+ const report = {
+ tag: 'testsuites',
+ name: 'summary_report',
+ timestamp: new Date().toDateString(),
+ time: '1',
+ errors: 0,
+ failures: 0,
+ tests: 0,
+ children: []
+ };
+ const rootSuite = this.suiteService.rootSuite;
+ if (rootSuite && rootSuite.childSuites) {
+ for (let testsuite of rootSuite.childSuites) {
+ let suiteReport = {
+ tag: 'testsuite',
+ name: testsuite['description'],
+ errors: 0,
+ tests: 0,
+ failures: 0,
+ time: '0.1',
+ children: []
+ };
+ let specs = testsuite['specs'];
+ for (let testcase of specs) {
+ report.tests++;
+ suiteReport.tests++;
+ let caseReport = {
+ tag: 'testcase',
+ name: testcase['description'],
+ status: 'run',
+ time: '0.0',
+ classname: testsuite['description']
+ };
+ if (testcase.error) {
+ caseReport['result'] = false;
+ caseReport['children'] = [{
+ tag: 'error',
+ type: '',
+ message: testcase.error.message
+ }];
+ report.errors++;
+ suiteReport.errors++;
+ } else if (testcase.result.failExpects.length > 0) {
+ caseReport['result'] = false;
+ let message = '';
+ testcase.result.failExpects.forEach(failExpect => {
+ message += failExpect.message || ('expect ' + failExpect.actualValue + ' ' + failExpect.checkFunc + ' ' + (failExpect.expectValue || '')) + ';';
+ });
+ caseReport['children'] = [{
+ tag: 'failure',
+ type: '',
+ message: message
+ }];
+ report.failures++;
+ suiteReport.failures++;
+ } else {
+ caseReport['result'] = true;
+ }
+ suiteReport.children.push(caseReport);
+ }
+ report.children.push(suiteReport);
+ }
+ }
+
+ let reportXml = '\n' + json2xml(report);
+ this.fileModule.writeText({
+ uri: 'internal://app/report.xml',
+ text: reportXml,
+ success: function () {
+ console.info('call success callback success');
+ },
+ fail: function (data, code) {
+ console.info('call fail callback success:');
+ },
+ complete: function () {
+ console.info('call complete callback success');
+ }
+ });
+ }
+}
+
+function json2xml(json) {
+ let tagName;
+ let hasChildren = false;
+ let childrenStr = '';
+ let attrStr = '';
+ for (let key in json) {
+ if (key === 'tag') {
+ tagName = json[key];
+ } else if (key === 'children') {
+ if (json[key].length > 0) {
+ hasChildren = true;
+ for (let child of json[key]) {
+ childrenStr += json2xml(child);
+ }
+ }
+ } else {
+ attrStr += ` ${key}="${json[key]}"`;
+ }
+ }
+ let xml = `<${tagName}${attrStr}`;
+ xml += hasChildren ? `>${childrenStr}${tagName}>` : '/>';
+ return xml;
+}
+
+export default ReportExtend;
diff --git a/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/service.js b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/service.js
new file mode 100644
index 0000000000000000000000000000000000000000..55d04a8fc206b3ffe52f80e90e07c3fbf56be687
--- /dev/null
+++ b/oh_modules/.ohpm/oh_modules/@ohos/hypium/src/main/service.js
@@ -0,0 +1,966 @@
+/*
+ * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import SysTestKit from "./module/kit/SysTestKit";
+import {TAG} from './Constant';
+
+class AssertException extends Error {
+ constructor(message) {
+ super();
+ this.name = "AssertException";
+ this.message = message;
+ }
+}
+
+function getFuncWithArgsZero(func, timeout, isStressTest) {
+ return new Promise(async (resolve, reject) => {
+ let timer = null;
+ if (!isStressTest) {
+ timer = setTimeout(() => {
+ reject(new Error('execute timeout ' + timeout + 'ms'));
+ }, timeout);
+ }
+ try {
+ await func();
+ } catch (err) {
+ reject(err);
+ }
+ timer !== null ? clearTimeout(timer) : null;
+ resolve();
+ });
+}
+
+function getFuncWithArgsOne(func, timeout, isStressTest) {
+ return new Promise(async (resolve, reject) => {
+ let timer = null;
+ if (!isStressTest) {
+ timer = setTimeout(() => {
+ reject(new Error('execute timeout ' + timeout + 'ms'));
+ }, timeout);;
+ }
+
+ function done() {
+ timer !== null ? clearTimeout(timer) : null;
+ resolve();
+ }
+
+ try {
+ await func(done);
+ } catch (err) {
+ timer !== null ? clearTimeout(timer) : null;
+ reject(err);
+ }
+ });
+}
+
+function getFuncWithArgsTwo(func, timeout, paramItem, isStressTest) {
+ return new Promise(async (resolve, reject) => {
+ let timer = null;
+ if (!isStressTest) {
+ timer = setTimeout(() => {
+ reject(new Error('execute timeout ' + timeout + 'ms'));
+ }, timeout);
+ }
+
+ function done() {
+ timer !== null ? clearTimeout(timer) : null;
+ resolve();
+ }
+
+ try {
+ await func(done, paramItem);
+ } catch (err) {
+ timer !== null ? clearTimeout(timer) : null;
+ reject(err);
+ }
+ });
+}
+
+function processFunc(coreContext, func) {
+ let argNames = ((func || '').toString()
+ .replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg, '')
+ .match(/^(function)?\s*[^\(]*\(\s*([^\)]*)\)/m) || ['', '', ''])[2]
+ .split(',') // split parameters
+ .map(item => item.replace(/^\s*(_?)(.+?)\1\s*$/, name => name.split('=')[0].trim()))
+ .filter(String);
+ let funcLen = func.length;
+ let processedFunc;
+ const config = coreContext.getDefaultService('config');
+ config.setSupportAsync(true);
+ const timeout = + (config.timeout === undefined ? 5000 : config.timeout);
+ const isStressTest = (coreContext.getServices('dataDriver') !== undefined || config.getStress() > 1);
+ switch (funcLen) {
+ case 0: {
+ processedFunc = function () {
+ return getFuncWithArgsZero(func, timeout, isStressTest);
+ };
+ break;
+ }
+ case 1: {
+ if (argNames[0] === 'data') {
+ processedFunc = function (paramItem) {
+ func(paramItem);
+ };
+ } else {
+ processedFunc = function () {
+ return getFuncWithArgsOne(func, timeout, isStressTest);
+ };
+ }
+ break;
+ }
+ default: {
+ processedFunc = function (paramItem) {
+ return getFuncWithArgsTwo(func, timeout, paramItem, isStressTest);
+ };
+ break;
+ }
+ }
+ return processedFunc;
+}
+
+function secureRandomNumber() {
+ return crypto.randomBytes(8).readUInt32LE() / 0xffffffff;
+}
+
+class SuiteService {
+ constructor(attr) {
+ this.id = attr.id;
+ this.rootSuite = new SuiteService.Suite({});
+ this.currentRunningSuite = this.rootSuite;
+ this.suitesStack = [this.rootSuite];
+ }
+
+ describe(desc, func) {
+ const configService = this.coreContext.getDefaultService('config');
+ if (configService.filterSuite(desc)) {
+ console.info(`${TAG}filter suite : ${desc}`);
+ return;
+ }
+ const suite = new SuiteService.Suite({description: desc});
+ if (typeof this.coreContext.getServices('dataDriver') !== 'undefined' && configService['dryRun'] !== 'true') {
+ let suiteStress = this.coreContext.getServices('dataDriver').dataDriver.getSuiteStress(desc);
+ for (let i = 1; i < suiteStress; i++) {
+ this.currentRunningSuite.childSuites.push(suite);
+ }
+ }
+ this.currentRunningSuite.childSuites.push(suite);
+ this.currentRunningSuite = suite;
+ this.suitesStack.push(suite);
+ func.call();
+ let childSuite = this.suitesStack.pop();
+ if (this.suitesStack.length === 0) {
+ this.currentRunningSuite = childSuite;
+ this.suitesStack.push(childSuite);
+ }
+ if (this.suitesStack.length > 1) {
+ this.currentRunningSuite = this.suitesStack.pop();
+ } else {
+ this.currentRunningSuite = this.suitesStack.pop();
+ this.suitesStack.push(this.currentRunningSuite);
+ }
+ }
+
+ beforeAll(func) {
+ this.currentRunningSuite.beforeAll.push(processFunc(this.coreContext, func));
+ }
+
+ beforeEach(func) {
+ this.currentRunningSuite.beforeEach.push(processFunc(this.coreContext, func));
+ }
+
+ afterAll(func) {
+ this.currentRunningSuite.afterAll.push(processFunc(this.coreContext, func));
+ }
+
+ afterEach(func) {
+ this.currentRunningSuite.afterEach.push(processFunc(this.coreContext, func));
+ }
+
+ getCurrentRunningSuite() {
+ return this.currentRunningSuite;
+ }
+
+ setCurrentRunningSuite(suite) {
+ this.currentRunningSuite = suite;
+ }
+
+ traversalResults(suite, obj, breakOnError) {
+ if (suite.childSuites.length === 0 && suite.specs.length === 0) {
+ return obj;
+ }
+ if (suite.specs.length > 0) {
+ for (const itItem of suite.specs) {
+ obj.total++;
+ if (breakOnError && (obj.error > 0 || obj.failure > 0)) { // breakOnError模式
+ continue;
+ }
+ if (itItem.error) {
+ obj.error++;
+ } else if (itItem.fail) {
+ obj.failure++;
+ } else if (itItem.pass === true) {
+ obj.pass++;
+ }
+ }
+ }
+
+ obj.duration += suite.duration;
+
+ if (suite.childSuites.length > 0) {
+ for (const suiteItem of suite.childSuites) {
+ this.traversalResults(suiteItem, obj, breakOnError);
+ }
+ }
+ }
+
+ async setSuiteResults(suite, error, coreContext) {
+ if (suite.childSuites.length === 0 && suite.specs.length === 0) {
+ return obj;
+ }
+ if (suite.specs.length > 0) {
+ const specService = coreContext.getDefaultService('spec');
+ for (const specItem of suite.specs) {
+ specService.setCurrentRunningSpec(specItem);
+ if (error instanceof AssertException) {
+ specItem.fail = error;
+ } else {
+ specItem.error = error;
+ }
+ await coreContext.fireEvents('spec', 'specStart', specItem);
+ await coreContext.fireEvents('spec', 'specDone', specItem);
+ }
+ }
+ if (suite.childSuites.length > 0) {
+ for (const suiteItem of suite.childSuites) {
+ await this.setSuiteResults(suiteItem, error, coreContext);
+ }
+ }
+ }
+
+ getSummary() {
+ let suiteService = this.coreContext.getDefaultService('suite');
+ let rootSuite = suiteService.rootSuite;
+ const specService = this.coreContext.getDefaultService('spec');
+ const configService = this.coreContext.getDefaultService('config');
+ let breakOnError = configService.isBreakOnError();
+ let isError = specService.getStatus();
+ let isBreaKOnError = breakOnError && isError;
+ let obj = {total: 0, failure: 0, error: 0, pass: 0, ignore: 0, duration: 0};
+ for (const suiteItem of rootSuite.childSuites) {
+ this.traversalResults(suiteItem, obj, isBreaKOnError);
+ }
+ obj.ignore = obj.total - obj.pass - obj.failure - obj.error;
+ return obj;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ }
+
+ traversalSuites(suite, obj, configService) {
+ if (suite.childSuites.length === 0 && suite.specs.length === 0) {
+ return [];
+ }
+ if (suite.specs.length > 0) {
+ let itArray = [];
+ for (const itItem of suite['specs']) {
+ if (!configService.filterDesc(suite.description, itItem.description, itItem.fi, null)) {
+ itArray.push({'itName': itItem.description});
+ }
+ }
+ obj[suite.description] = itArray;
+ }
+
+ if (suite.childSuites.length > 0) {
+ let suiteArray = [];
+ for (const suiteItem of suite.childSuites) {
+ let suiteObj = {};
+ this.traversalSuites(suiteItem, suiteObj, configService);
+ if (!configService.filterSuite(suiteItem.description)) {
+ suiteArray.push(suiteObj);
+ }
+ }
+ obj.suites = suiteArray;
+ }
+ }
+
+ async dryRun(abilityDelegator) {
+ const configService = this.coreContext.getDefaultService('config');
+ let testSuitesObj = {};
+ let suitesArray = [];
+ for (const suiteItem of this.rootSuite.childSuites) {
+ let obj = {};
+ this.traversalSuites(suiteItem, obj, configService);
+ if (!configService.filterSuite(suiteItem.description)) {
+ suitesArray.push(obj);
+ }
+ }
+ testSuitesObj['suites'] = suitesArray;
+
+ let strJson = JSON.stringify(testSuitesObj);
+ let strLen = strJson.length;
+ let maxLen = 500;
+ let maxCount = Math.floor(strLen / maxLen);
+
+ for (let count = 0; count <= maxCount; count++) {
+ await SysTestKit.print(strJson.substring(count * maxLen, (count + 1) * maxLen));
+ }
+ console.info(`${TAG}dryRun print success`);
+ abilityDelegator.finishTest('dry run finished!!!', 0, () => { });
+ }
+
+ execute() {
+ const configService = this.coreContext.getDefaultService('config');
+ if (configService.filterValid.length !== 0) {
+ this.coreContext.fireEvents('task', 'incorrectFormat');
+ return;
+ }
+
+ if (configService.isRandom() && this.rootSuite.childSuites.length > 0) {
+ this.rootSuite.childSuites.sort(function () {
+ return Math.random().toFixed(1) > 0.5 ? -1 : 1;
+ });
+ this.currentRunningSuite = this.rootSuite.childSuites[0];
+ }
+
+ if (configService.isSupportAsync()) {
+ let asyncExecute = async () => {
+ await this.coreContext.fireEvents('task', 'taskStart');
+ await this.rootSuite.asyncRun(this.coreContext);
+ };
+ asyncExecute().then(async () => {
+ await this.coreContext.fireEvents('task', 'taskDone');
+ });
+ } else {
+ this.coreContext.fireEvents('task', 'taskStart');
+ this.rootSuite.run(this.coreContext);
+ this.coreContext.fireEvents('task', 'taskDone');
+ }
+ }
+
+ apis() {
+ const _this = this;
+ return {
+ describe: function (desc, func) {
+ return _this.describe(desc, func);
+ },
+ beforeAll: function (func) {
+ return _this.beforeAll(func);
+ },
+ beforeEach: function (func) {
+ return _this.beforeEach(func);
+ },
+ afterAll: function (func) {
+ return _this.afterAll(func);
+ },
+ afterEach: function (func) {
+ return _this.afterEach(func);
+ }
+ };
+ }
+}
+
+SuiteService.Suite = class {
+ constructor(attrs) {
+ this.description = attrs.description || '';
+ this.childSuites = [];
+ this.specs = [];
+ this.beforeAll = [];
+ this.afterAll = [];
+ this.beforeEach = [];
+ this.afterEach = [];
+ this.duration = 0;
+ this.hookError = null;
+ }
+
+ pushSpec(spec) {
+ this.specs.push(spec);
+ }
+
+ removeSpec(desc) {
+ this.specs = this.specs.filter((item, index) => {
+ return item.description !== desc;
+ });
+ }
+
+ getSpecsNum() {
+ return this.specs.length;
+ }
+
+ isRun(coreContext) {
+ const configService = coreContext.getDefaultService('config');
+ const suiteService = coreContext.getDefaultService('suite');
+ const specService = coreContext.getDefaultService('spec');
+ let breakOnError = configService.isBreakOnError();
+ let isError = specService.getStatus();
+ return breakOnError && isError;
+ }
+
+ run(coreContext) {
+ const suiteService = coreContext.getDefaultService('suite');
+ suiteService.setCurrentRunningSuite(this);
+ if (this.description !== '') {
+ coreContext.fireEvents('suite', 'suiteStart', this);
+ }
+ this.runHookFunc('beforeAll');
+ if (this.specs.length > 0) {
+ const configService = coreContext.getDefaultService('config');
+ if (configService.isRandom()) {
+ this.specs.sort(function () {
+ return Math.random().toFixed(1) > 0.5 ? -1 : 1;
+ });
+ }
+ for (let spec in this.specs) {
+ let isBreakOnError = this.isRun(coreContext);
+ if (isBreakOnError) {
+ break;
+ }
+ this.runHookFunc('beforeEach');
+ spec.run(coreContext);
+ this.runHookFunc('afterEach');
+ }
+ }
+ if (this.childSuites.length > 0) {
+ for (let suite in this.childSuites) {
+ let isBreakOnError = this.isRun(coreContext);
+ if (isBreakOnError) {
+ break;
+ }
+ suite.run(coreContext);
+ suiteService.setCurrentRunningSuite(suite);
+ }
+ }
+ this.runHookFunc('afterAll');
+ if (this.description !== '') {
+ coreContext.fireEvents('suite', 'suiteDone');
+ }
+ }
+
+ async asyncRunSpecs(coreContext) {
+ const configService = coreContext.getDefaultService('config');
+ if (configService.isRandom()) {
+ this.specs.sort(function () {
+ return Math.random().toFixed(1) > 0.5 ? -1 : 1;
+ });
+ }
+ const specService = coreContext.getDefaultService('spec');
+ for (let specItem of this.specs) {
+ specService.setCurrentRunningSpec(specItem);
+ // 遇错即停模式,发现用例有问题,直接返回,不在执行后面的it
+ let isBreakOnError = this.isRun(coreContext);
+ if (isBreakOnError) {
+ console.log("break description :" + this.description);
+ break;
+ }
+ await coreContext.fireEvents('spec', 'specStart', specItem);
+ try {
+ await this.runAsyncHookFunc('beforeEach');
+ await specItem.asyncRun(coreContext);
+ await this.runAsyncHookFunc('afterEach');
+ } catch (e) {
+ console.error(`${TAG}${e?.stack}`);
+ if (e instanceof AssertException) {
+ specItem.fail = e;
+ } else {
+ specItem.error = e;
+ }
+ specService.setStatus(true);
+ }
+ specItem.setResult();
+ await coreContext.fireEvents('spec', 'specDone', specItem);
+ specService.setCurrentRunningSpec(null);
+ }
+ }
+
+ async asyncRunChildSuites(coreContext) {
+ for (let i = 0; i < this.childSuites.length; i++) {
+ // 遇错即停模式, 发现用例有问题,直接返回,不在执行后面的description
+ let isBreakOnError = this.isRun(coreContext);
+ if (isBreakOnError) {
+ console.log(`${TAG}break description : ${this.description}`);
+ break;
+ }
+ await this.childSuites[i].asyncRun(coreContext);
+ }
+ }
+
+ async asyncRun(coreContext) {
+ const suiteService = coreContext.getDefaultService('suite');
+ const specService = coreContext.getDefaultService('spec');
+
+ suiteService.setCurrentRunningSuite(this);
+ suiteService.suitesStack.push(this);
+ if (this.description !== '') {
+ await coreContext.fireEvents('suite', 'suiteStart', this);
+ }
+
+ try {
+ await this.runAsyncHookFunc('beforeAll');
+ } catch (error) {
+ console.error(`${TAG}${error?.stack}`);
+ this.hookError = error;
+ }
+
+ if (this.hookError !== null) {
+ specService.setStatus(true);
+ await suiteService.setSuiteResults(this, this.hookError, coreContext);
+ }
+
+ if (this.specs.length > 0 && this.hookError === null) {
+ await this.asyncRunSpecs(coreContext);
+ }
+
+ if (this.childSuites.length > 0 && this.hookError === null) {
+ await this.asyncRunChildSuites(coreContext);
+ }
+
+ try {
+ await this.runAsyncHookFunc('afterAll');
+ } catch (error) {
+ console.error(`${TAG}${error?.stack}`);
+ this.hookError = error;
+ specService.setStatus(true);
+ }
+
+ if (this.description !== '') {
+ await coreContext.fireEvents('suite', 'suiteDone');
+ let childSuite = suiteService.suitesStack.pop();
+ if (suiteService.suitesStack.length === 0) {
+ suiteService.suitesStack.push(childSuite);
+ }
+ if (suiteService.suitesStack.length > 1) {
+ suiteService.setCurrentRunningSuite(suiteService.suitesStack.pop());
+ } else {
+ let currentRunningSuite = suiteService.suitesStack.pop();
+ suiteService.setCurrentRunningSuite(currentRunningSuite);
+ suiteService.suitesStack.push(currentRunningSuite);
+ }
+ }
+ }
+
+ runHookFunc(hookName) {
+ if (this[hookName] && this[hookName].length > 0) {
+ this[hookName].forEach(func => {
+ try {
+ func();
+ } catch (e) {
+ console.error(`${TAG}${e.stack}`);
+ }
+ });
+ }
+ }
+
+ async runAsyncHookFunc(hookName) {
+ for (const hookItem of this[hookName]) {
+ try {
+ await hookItem();
+ } catch (error) {
+ error['message'] += `, error in ${hookName} function`;
+ throw error;
+ }
+
+ }
+ }
+};
+
+class SpecService {
+ constructor(attr) {
+ this.id = attr.id;
+ this.totalTest = 0;
+ this.hasError = false;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ }
+
+ setCurrentRunningSpec(spec) {
+ this.currentRunningSpec = spec;
+ }
+
+ setStatus(obj) {
+ this.hasError = obj;
+ }
+
+ getStatus() {
+ return this.hasError;
+ }
+
+ getTestTotal() {
+ return this.totalTest;
+ }
+
+ getCurrentRunningSpec() {
+ return this.currentRunningSpec;
+ }
+
+ it(desc, filter, func) {
+ const configService = this.coreContext.getDefaultService('config');
+ const currentSuiteName = this.coreContext.getDefaultService('suite').getCurrentRunningSuite().description;
+ if (configService.filterDesc(currentSuiteName, desc, filter, this.coreContext)) {
+ console.info(`${TAG}filter it :${desc}`);
+ } else {
+ let processedFunc = processFunc(this.coreContext, func);
+ const spec = new SpecService.Spec({description: desc, fi: filter, fn: processedFunc});
+ const suiteService = this.coreContext.getDefaultService('suite');
+ if (typeof this.coreContext.getServices('dataDriver') !== 'undefined' && configService['dryRun'] !== 'true') {
+ let specStress = this.coreContext.getServices('dataDriver').dataDriver.getSpecStress(desc);
+ for (let i = 1; i < specStress; i++) {
+ this.totalTest++;
+ suiteService.getCurrentRunningSuite().pushSpec(spec);
+ }
+ }
+
+ // dryRun 状态下不统计压力测试重复数据
+ if (configService['dryRun'] !== 'true') {
+ let stress = configService.getStress(); // 命令配置压力测试
+ console.info(`${TAG}stress length : ${stress}`);
+ for (let i = 1; i < stress; i++) {
+ this.totalTest++;
+ suiteService.getCurrentRunningSuite().pushSpec(spec);
+ }
+ }
+ this.totalTest++;
+ suiteService.getCurrentRunningSuite().pushSpec(spec);
+ }
+ }
+
+ apis() {
+ const _this = this;
+ return {
+ it: function (desc, filter, func) {
+ return _this.it(desc, filter, func);
+ }
+ };
+ }
+}
+
+SpecService.Spec = class {
+ constructor(attrs) {
+ this.description = attrs.description || '';
+ this.fi = attrs.fi;
+ this.fn = attrs.fn || function () {
+ };
+ this.fail = undefined;
+ this.error = undefined;
+ this.duration = 0;
+ this.startTime = 0;
+ this.isExecuted = false; // 当前用例是否执行
+ }
+
+ setResult() {
+ if (this.fail) {
+ this.pass = false;
+ } else {
+ this.pass = true;
+ }
+ }
+
+ run(coreContext) {
+ const specService = coreContext.getDefaultService('spec');
+ specService.setCurrentRunningSpec(this);
+ coreContext.fireEvents('spec', 'specStart', this);
+ this.isExecuted = true;
+ try {
+ let dataDriver = coreContext.getServices('dataDriver');
+ if (typeof dataDriver === 'undefined') {
+ this.fn();
+ } else {
+ let suiteParams = dataDriver.dataDriver.getSuiteParams();
+ let specParams = dataDriver.dataDriver.getSpecParams();
+ console.info(`${TAG}[suite params] ${JSON.stringify(suiteParams)}`);
+ console.info(`${TAG}[spec params] ${JSON.stringify(specParams)}`);
+ if (this.fn.length === 0) {
+ this.fn();
+ } else if (specParams.length === 0) {
+ this.fn(suiteParams);
+ } else {
+ specParams.forEach(paramItem => this.fn(Object.assign({}, paramItem, suiteParams)));
+ }
+ }
+ this.setResult();
+ } catch (e) {
+ this.error = e;
+ specService.setStatus(true);
+ }
+ coreContext.fireEvents('spec', 'specDone', this);
+ }
+
+ async asyncRun(coreContext) {
+ const dataDriver = coreContext.getServices('dataDriver');
+ if (typeof dataDriver === 'undefined') {
+ await this.fn();
+ } else {
+ const suiteParams = dataDriver.dataDriver.getSuiteParams();
+ const specParams = dataDriver.dataDriver.getSpecParams();
+ console.info(`[suite params] ${JSON.stringify(suiteParams)}`);
+ console.info(`[spec params] ${JSON.stringify(specParams)}`);
+ if (this.fn.length === 0) {
+ await this.fn();
+ } else if (specParams.length === 0) {
+ await this.fn(suiteParams);
+ } else {
+ for (const paramItem of specParams) {
+ await this.fn(Object.assign({}, paramItem, suiteParams));
+ }
+ }
+ }
+
+ this.isExecuted = true;
+ }
+
+ filterCheck(coreContext) {
+ const specService = coreContext.getDefaultService('spec');
+ specService.setCurrentRunningSpec(this);
+ return true;
+ }
+};
+
+class ExpectService {
+ constructor(attr) {
+ this.id = attr.id;
+ this.matchers = {};
+ }
+
+ expect(actualValue) {
+ return this.wrapMatchers(actualValue);
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ this.addMatchers(this.basicMatchers());
+ }
+
+ addMatchers(matchers) {
+ for (const matcherName in matchers) {
+ if (Object.prototype.hasOwnProperty.call(matchers, matcherName)) {
+ this.matchers[matcherName] = matchers[matcherName];
+ }
+ }
+ }
+
+ basicMatchers() {
+ return {
+ assertTrue: function (actualValue) {
+ return {
+ pass: (actualValue) === true,
+ message: 'expect true, actualValue is ' + actualValue
+ };
+ },
+ assertEqual: function (actualValue, args) {
+ return {
+ pass: (actualValue) === args[0],
+ expectValue: args[0],
+ message: 'expect ' + actualValue + ' equals ' + args[0]
+ };
+ },
+ assertThrow: function (actual, args) {
+ const result = {
+ pass: false
+ };
+ if (typeof actual !== 'function') {
+ result.message = 'toThrow\'s Actual should be a Function';
+ } else {
+ let hasThrow = false;
+ let throwError;
+ try {
+ actual();
+ } catch (e) {
+ hasThrow = true;
+ throwError = e;
+ }
+ if (!hasThrow) {
+ result.message = 'function did not throw an exception';
+ } else if (throwError && throwError.message === args[0]) {
+ result.pass = true;
+ } else {
+ result.message = `expect to throw ${args[0]} , actual throw ${throwError.message}`;
+ }
+ }
+ return result;
+ }
+ };
+ }
+
+ wrapMatchers(actualValue) {
+ const _this = this;
+ const wrappedMatchers = {
+ // 翻转标识
+ isNot: false,
+
+ // 翻转方法
+ not: function () {
+ this.isNot = true;
+ return this;
+ }
+ };
+ const specService = _this.coreContext.getDefaultService('spec');
+ const currentRunningSpec = specService.getCurrentRunningSpec();
+ const currentRunningSuite = _this.coreContext.getDefaultService('suite').getCurrentRunningSuite();
+ for (const matcherName in this.matchers) {
+ let result = Object.prototype.hasOwnProperty.call(this.matchers, matcherName);
+ if (!result) {
+ continue;
+ }
+ if (matcherName.search('assertPromise') == 0) {
+ wrappedMatchers[matcherName] = async function () {
+ await _this.matchers[matcherName](actualValue, arguments).then(function (result) {
+ if (wrappedMatchers.isNot) {
+ result.pass = !result.pass;
+ }
+ result.actualValue = actualValue;
+ result.checkFunc = matcherName;
+ if (!result.pass) {
+ const assertError = new AssertException(result.message);
+ currentRunningSpec ? currentRunningSpec.fail = assertError : currentRunningSuite.hookError = assertError;
+ throw assertError;
+ }
+ });
+ };
+ } else {
+ wrappedMatchers[matcherName] = function () {
+ const result = _this.matchers[matcherName](actualValue, arguments);
+ if (wrappedMatchers.isNot) {
+ result.pass = !result.pass;
+ }
+ result.actualValue = actualValue;
+ result.checkFunc = matcherName;
+ if (!result.pass) {
+ const assertError = new AssertException(result.message);
+ currentRunningSpec ? currentRunningSpec.fail = assertError : currentRunningSuite.hookError = assertError;
+ throw assertError;
+ }
+ };
+ }
+ }
+ return wrappedMatchers;
+ }
+
+ apis() {
+ const _this = this;
+ return {
+ expect: function (actualValue) {
+ return _this.expect(actualValue);
+ }
+ };
+ }
+}
+
+class ReportService {
+ constructor(attr) {
+ this.id = attr.id;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ this.specService = this.coreContext.getDefaultService('spec');
+ this.suiteService = this.coreContext.getDefaultService('suite');
+ this.duration = 0;
+ }
+
+ taskStart() {
+ console.info(`${TAG}[start] start run suites`);
+ }
+
+ async suiteStart() {
+ console.info(`${TAG}[suite start]${this.suiteService.getCurrentRunningSuite().description}`);
+ }
+
+ async specStart() {
+ console.info(`${TAG}start running case '${this.specService.currentRunningSpec.description}'`);
+ this.index = this.index + 1;
+ let spec = this.specService.currentRunningSpec;
+ spec.startTime = await SysTestKit.getRealTime();
+ }
+
+ async specDone() {
+ let msg = '';
+ let spec = this.specService.currentRunningSpec;
+ let suite = this.suiteService.currentRunningSuite;
+ spec.duration = await SysTestKit.getRealTime() - spec.startTime;
+ suite.duration += spec.duration;
+ if (spec.error) {
+ this.formatPrint('error', spec.description + ' ; consuming ' + spec.duration + 'ms');
+ this.formatPrint('errorDetail', spec.error);
+ } else if (spec.fail) {
+ this.formatPrint('fail', spec.description + ' ; consuming ' + spec.duration + 'ms');
+ this.formatPrint('failDetail', spec.fail?.message);
+ } else {
+ this.formatPrint('pass', spec.description + ' ; consuming ' + spec.duration + 'ms');
+ }
+ this.formatPrint(this.specService.currentRunningSpec.error, msg);
+ }
+
+ suiteDone() {
+ let suite = this.suiteService.currentRunningSuite;
+ let message = suite.hookError ? `, ${suite.hookError?.message}` : '';
+ console.info(`[suite end] ${suite.description} consuming ${suite.duration} ms${message}`);
+ }
+
+ taskDone() {
+ let msg = '';
+ let summary = this.suiteService.getSummary();
+ msg = 'total cases:' + summary.total + ';failure ' + summary.failure + ',' + 'error ' + summary.error;
+ msg += ',pass ' + summary.pass + '; consuming ' + summary.duration + 'ms';
+ console.info(`${TAG}${msg}`);
+ console.info(`${TAG}[end] run suites end`);
+ }
+
+ incorrectFormat() {
+ if (this.coreContext.getDefaultService('config').filterValid.length !== 0) {
+ this.coreContext.getDefaultService('config').filterValid.forEach(function (item) {
+ console.info(`${TAG}this param ${item} is invalid`);
+ });
+ }
+ }
+
+ formatPrint(type, msg) {
+ switch (type) {
+ case 'pass':
+ console.info(`${TAG}[pass]${msg}`);
+ break;
+ case 'fail':
+ console.info(`${TAG}[fail]${msg}`);
+ break;
+ case 'failDetail':
+ console.info(`${TAG}[failDetail]${msg}`);
+ break;
+ case 'error':
+ console.info(`${TAG}[error]${msg}`);
+ break;
+ case 'errorDetail':
+ console.info(`${TAG}[errorDetail]${msg}`);
+ break;
+ }
+ }
+
+ sleep(numberMillis) {
+ var now = new Date();
+ var exitTime = now.getTime() + numberMillis;
+ while (true) {
+ now = new Date();
+ if (now.getTime() > exitTime) {
+ return;
+ }
+ }
+ }
+}
+
+export {
+ SuiteService,
+ SpecService,
+ ExpectService,
+ ReportService
+};
diff --git a/oh_modules/@ohos/hypium/CHANGELOG.md b/oh_modules/@ohos/hypium/CHANGELOG.md
new file mode 100644
index 0000000000000000000000000000000000000000..79c11d2bdeba38bc18f0f3bdf4723e4f1d77263b
--- /dev/null
+++ b/oh_modules/@ohos/hypium/CHANGELOG.md
@@ -0,0 +1,50 @@
+## 1.0.9
+
+- 测试hook方法支持断言与异常
+- 修复不能mock静态方法的问题
+
+## 1.0.6
+
+- 适配模块化编译
+- 适配IDE覆盖率数据输出
+
+## 1.0.5
+
+- 优化接口异常场景处理能力
+- 修复大规模压力测试下内存溢出问题
+- 修复测试脚本定义扩展原型方法与框架的兼容性问题
+- 异步promise状态判断断言与取反断言兼容
+
+## 1.0.4
+
+- 新增异步promise状态判断断言
+- 新增基础数据判断断言
+- 新增断言异常信息描述
+- 优化用例计时逻辑,采用相对时间计时
+- 修改用例执行过程,异步执行
+- 修复用例结果偶现的乱序问题
+
+## 1.0.3
+
+- 新增mock对象的能力,支持mock无参数函数
+- 新增测试套、测试用例随机执行功能
+- 解决测试套声明不规范,导致用例加载异常的问题
+- 修复命令行窗口输出乱序的问题
+
+## 1.0.2
+
+- 新增mock接口,判断当前mock方法状态、使用次数
+- 修复用例耗时统计问题
+- 修改断言功能,断言失败后,会抛出异常
+
+## 1.0.1
+- 新增mock基础能力
+- 修复部分断言失败后,消息提示异常问题
+
+## 1.0.0
+- 新增应用日志关键字查询接口,查询hilog日志中是否包含指定字符串
+- 支持用例筛选功能,用于指定测试用例的执行。可按用例名称、类型、规模、级别与测试套名称筛选
+- 支持新SDK下单元测试
+- 支持dry run 功能,通过命令行传参数,返回当前测试套用例名称全集
+- 新增框架接口声明文件,用于deveco联想
+- 修复用例状态统计问题
\ No newline at end of file
diff --git a/oh_modules/@ohos/hypium/LICENSE b/oh_modules/@ohos/hypium/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..4947287f7b5ccb5d1e8b7b2d3aa5d89f322c160d
--- /dev/null
+++ b/oh_modules/@ohos/hypium/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
\ No newline at end of file
diff --git a/oh_modules/@ohos/hypium/README.md b/oh_modules/@ohos/hypium/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..83ddccc702c7b280100436d0a428bae203eb7f4b
--- /dev/null
+++ b/oh_modules/@ohos/hypium/README.md
@@ -0,0 +1,219 @@
+
Hypium
+
A unit test framework for OpenHarmonyOS application
+
+## Hypium是什么?
+***
+- Hypium是OpenHarmony上的测试框架,提供测试用例编写、执行、结果显示能力,用于OpenHarmony系统应用接口以及应用界面测试。
+- Hypium结构化模型:hypium工程主要由List.test.js与TestCase.test.js组成。
+```
+rootProject // Hypium工程根目录
+├── moduleA
+│ ├── src
+│ ├── main // 被测试应用目录
+│ ├── ohosTest // 测试用例目录
+│ ├── js/ets
+│ └── test
+│ └── List.test.js // 测试用例加载脚本,ets目录下为.ets后缀
+│ └── TestCase.test.js // 测试用例脚本,ets目录下为.ets后缀
+└── moduleB
+ ...
+│ └── List.test.js // 测试用例加载脚本,ets目录下为.ets后缀
+│ └── TestCase.test.js // 测试用例脚本,ets目录下为.ets后缀
+```
+
+## 安装使用
+***
+- 在DevEco Studio内使用Hypium
+- 工程级package.json内配置:
+```json
+"dependencies": {
+ "@ohos/hypium": "1.0.9"
+}
+```
+注:
+hypium服务于OpenHarmonyOS应用对外接口测试、系统对外接口测试(SDK中接口),完成HAP自动化测试。详细指导:
+[Deveco Studio](https://developer.harmonyos.com/cn/develop/deveco-studio)
+
+#### 通用语法
+
+- 测试用例采用业内通用语法,describe代表一个测试套, it代表一条用例。
+
+| No. | API | 功能说明 |
+| --- | ---------- | ---------------------------------------------------------------------------------------------------------------------- |
+| 1 | describe | 定义一个测试套,支持两个参数:测试套名称和测试套函数 |
+| 2 | beforeAll | 在测试套内定义一个预置条件,在所有测试用例开始前执行且仅执行一次,支持一个参数:预置动作函数 |
+| 3 | beforeEach | 在测试套内定义一个单元预置条件,在每条测试用例开始前执行,执行次数与it定义的测试用例数一致,支持一个参数:预置动作函数 |
+| 4 | afterEach | 在测试套内定义一个单元清理条件,在每条测试用例结束后执行,执行次数与it定义的测试用例数一致,支持一个参数:清理动作函数 |
+| 5 | afterAll | 在测试套内定义一个清理条件,在所有测试用例结束后执行且仅执行一次,支持一个参数:清理动作函数 |
+| 6 | it | 定义一条测试用例,支持三个参数:用例名称,过滤参数和用例函数 |
+| 7 | expect | 支持bool类型判断等多种断言方法 |
+
+#### 断言库
+
+- 示例代码:
+
+```javascript
+ expect(${actualvalue}).assertX(${expectvalue})
+```
+
+- 断言功能列表:
+
+| No. | API | 功能说明 |
+| :--- | :------------------------------- | ---------------------------------------------------------------------------------------------- |
+| 1 | assertClose | 检验actualvalue和expectvalue(0)的接近程度是否是expectValue(1) |
+| 2 | assertContain | 检验actualvalue中是否包含expectvalue |
+| 3 | assertDeepEquals | @since1.0.4 检验actualvalue和expectvalue(0)是否是同一个对象 |
+| 4 | assertEqual | 检验actualvalue是否等于expectvalue[0] |
+| 5 | assertFail | 抛出一个错误 |
+| 6 | assertFalse | 检验actualvalue是否是false |
+| 7 | assertTrue | 检验actualvalue是否是true |
+| 8 | assertInstanceOf | 检验actualvalue是否是expectvalue类型 |
+| 9 | assertLarger | 检验actualvalue是否大于expectvalue |
+| 10 | assertLess | 检验actualvalue是否小于expectvalue |
+| 11 | assertNaN | @since1.0.4 检验actualvalue是否是NaN |
+| 12 | assertNegUnlimited | @since1.0.4 检验actualvalue是否等于Number.NEGATIVE_INFINITY |
+| 13 | assertNull | 检验actualvalue是否是null |
+| 14 | assertPosUnlimited | @since1.0.4 检验actualvalue是否等于Number.POSITIVE_INFINITY |
+| 15 | assertPromiseIsPending | @since1.0.4 检验actualvalue是否处于Pending状态【actualvalue为promse对象】 |
+| 16 | assertPromiseIsRejected | @since1.0.4 检验actualvalue是否处于Rejected状态【同15】 |
+| 17 | assertPromiseIsRejectedWith | @since1.0.4 检验actualvalue是否处于Rejected状态,并且比较执行的结果值【同15】 |
+| 18 | assertPromiseIsRejectedWithError | @since1.0.4 检验actualvalue是否处于Rejected状态并有异常,同时比较异常的类型和message值【同15】 |
+| 19 | assertPromiseIsResolved | @since1.0.4 检验actualvalue是否处于Resolved状态【同15】 |
+| 20 | assertPromiseIsResolvedWith | @since1.0.4 检验actualvalue是否处于Resolved状态,并且比较执行的结果值【同15】 |
+| 21 | assertThrowError | 检验actualvalue抛出Error内容是否是expectValue |
+| 22 | assertUndefined | 检验actualvalue是否是undefined |
+| 23 | not | @since1.0.4 断言结果取反 |
+
+
+ 示例代码:
+
+```javascript
+ import { describe, it, expect } from '@ohos/hypium';
+
+ export default async function assertCloseTest() {
+ describe('assertClose', function () {
+ it('assertClose_success', 0, function () {
+ let a = 100;
+ let b = 0.1;
+ expect(a).assertClose(99, b);
+ })
+ })
+ }
+```
+
+#### 公共系统能力
+
+| No. | API | 功能描述 |
+| ---- | ------------------------------------------------------- | ------------------------------------------------------------ |
+| 1 | existKeyword(keyword: string, timeout: number): boolean | @since1.0.3 hilog日志中查找指定字段是否存在,keyword是待查找关键字,timeout为设置的查找时间 |
+| 2 | actionStart(tag: string): void | @since1.0.3 cmd窗口输出开始tag |
+| 3 | actionEnd(tag: string): void | @since1.0.3 cmd窗口输出结束tag |
+
+ 示例代码:
+
+```javascript
+import { describe, it, expect, SysTestKit} from '@ohos/hypium';
+
+export default function existKeywordTest() {
+ describe('existKeywordTest', function () {
+ it('existKeyword',DEFAULT, async function () {
+ console.info("HelloTest");
+ let isExist = await SysTestKit.existKeyword('HelloTest');
+ console.info('isExist ------>' + isExist);
+ })
+ })
+}
+```
+```javascript
+import { describe, it, expect, SysTestKit} from '@ohos/hypium';
+
+export default function actionTest() {
+ describe('actionTest', function () {
+ it('existKeyword',DEFAULT, async function () {
+ let tag = '[MyTest]';
+ SysTestKit.actionStart(tag);
+ //do something
+ SysTestKit.actionEnd(tag);
+ })
+ })
+}
+```
+
+#### 专项能力
+
+- 测试用例属性筛选能力:hypium支持根据用例属性筛选执行指定测试用例,使用方式是先在测试用例上标记用例属性后,再在测试应用的启动shell命令后新增" -s ${Key} ${Value}"。
+
+| Key | 含义说明 | Value取值范围 |
+| -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| level | 用例级别 | "0","1","2","3","4", 例如:-s level 1 |
+| size | 用例粒度 | "small","medium","large", 例如:-s size small |
+| testType | 用例测试类型 | "function","performance","power","reliability","security","global","compatibility","user","standard","safety","resilience", 例如:-s testType function |
+
+ 示例代码
+
+```javascript
+import { describe, it, expect, TestType, Size, Level } from '@ohos/hypium';
+
+export default function attributeTest() {
+ describe('attributeTest', function () {
+ it("testAttributeIt", TestType.FUNCTION | Size.SMALLTEST | Level.LEVEL0, function () {
+ console.info('Hello Test');
+ })
+ })
+}
+```
+
+ 示例命令
+```shell
+XX -s level 1 -s size small -s testType function
+```
+该命令的作用是:筛选测试应用中同时满足a)用例级别是1 b)用例粒度是small c)用例测试类型是function 三个条件的用例执行。
+
+- 测试套/测试用例名称筛选能力(测试套与用例名称用“#”号连接,多个用“,”英文逗号分隔)
+
+| Key | 含义说明 | Value取值范围 |
+| -------- | ----------------------- | -------------------------------------------------------------------------------------------- |
+| class | 指定要执行的测试套&用例 | ${describeName}#${itName},${describeName} , 例如:-s class attributeTest#testAttributeIt |
+| notClass | 指定不执行的测试套&用例 | ${describeName}#${itName},${describeName} , 例如:-s notClass attributeTest#testAttributeIt |
+
+ 示例命令
+```shell
+XX -s class attributeTest#testAttributeIt,abilityTest#testAbilityIt
+```
+该命令的作用是:筛选测试应用中attributeTest测试套下的testAttributeIt测试用例,abilityTest测试套下的testAbilityIt测试用例,只执行这两条用例。
+
+- 其他能力
+
+| 能力项 | Key | 含义说明 | Value取值范围 |
+| ------------ | ------- | ---------------------------- | ---------------------------------------------- |
+| 随机执行能力 | random | 测试套&测试用例随机执行 | true, 不传参默认为false, 例如:-s random true |
+| 空跑能力 | dryRun | 显示要执行的测试用例信息全集 | true , 不传参默认为false,例如:-s dryRun true |
+| 异步超时能力 | timeout | 异步用例执行的超时时间 | 正整数 , 单位ms,例如:-s timeout 5000 |
+
+##### 约束限制
+随机执行能力和空跑能力从npm包1.0.3版本开始支持
+
+#### Mock能力
+
+##### 约束限制
+
+单元测试框架Mock能力从npm包[1.0.1版本](https://repo.harmonyos.com/#/cn/application/atomService/@ohos%2Fhypium/v/1.0.1)开始支持
+
+## 约束
+
+***
+ 本模块首批接口从OpenHarmony SDK API version 8开始支持。
+
+## Hypium开放能力隐私声明
+
+- 我们如何收集和使用您的个人信息
+ 您在使用集成了Hypium开放能力的测试应用时,Hypium不会处理您的个人信息。
+- SDK处理的个人信息
+ 不涉及。
+- SDK集成第三方服务声明
+ 不涉及。
+- SDK数据安全保护
+ 不涉及。
+- SDK版本更新声明
+ 为了向您提供最新的服务,我们会不时更新Hypium版本。我们强烈建议开发者集成使用最新版本的Hypium。
+
diff --git a/oh_modules/@ohos/hypium/index.d.ts b/oh_modules/@ohos/hypium/index.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b0b4394a3284c07e873e84c9144cd31889e1863d
--- /dev/null
+++ b/oh_modules/@ohos/hypium/index.d.ts
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export const DEFAULT = 0B0000
+
+export const when: when;
+
+export enum TestType {
+ FUNCTION = 0B1,
+ PERFORMANCE = 0B1 << 1,
+ POWER = 0B1 << 2,
+ RELIABILITY = 0B1 << 3,
+ SECURITY = 0B1 << 4,
+ GLOBAL = 0B1 << 5,
+ COMPATIBILITY = 0B1 << 6,
+ USER = 0B1 << 7,
+ STANDARD = 0B1 << 8,
+ SAFETY = 0B1 << 9,
+ RESILIENCE = 0B1 << 10
+}
+
+export enum Size {
+ SMALLTEST = 0B1 << 16,
+ MEDIUMTEST = 0B1 << 17,
+ LARGETEST = 0B1 << 18
+}
+
+export enum Level {
+ LEVEL0 = 0B1 << 24,
+ LEVEL1 = 0B1 << 25,
+ LEVEL2 = 0B1 << 26,
+ LEVEL3 = 0B1 << 27,
+ LEVEL4 = 0B1 << 28
+}
+
+export function describe(testSuiteName: string, callback: Function): void
+
+export function beforeEach(callback: Function): void
+
+export function afterEach(callback: Function): void
+
+export function beforeAll(callback: Function): void
+
+export function afterAll(callback: Function): void
+
+export function it(testCaseName: string, attribute: (TestType | Size | Level), callback: Function)
+
+export interface Assert {
+ assertClose(expectValue: number, precision: number): void
+ assertContain(expectValue: any): void
+ assertEqual(expectValue: any): void
+ assertFail(): void
+ assertFalse(): void
+ assertTrue(): void
+ assertInstanceOf(expectValue: string): void
+ assertLarger(expectValue: number): void
+ assertLess(expectValue: number): void
+ assertNull(): void
+ assertThrowError(expectValue: string): void
+ assertUndefined(): void
+ assertLargerOrEqual(expectValue: number):void
+ assertLessOrEqual(expectValue: number):void
+ assertNaN():void
+ assertNegUnlimited(): void
+ assertPosUnlimited(): void
+ not(): Assert;
+ assertDeepEquals(expectValue: any):void
+ assertPromiseIsPending(): void
+ assertPromiseIsRejected(): void
+ assertPromiseIsRejectedWith(expectValue?: any): void
+ assertPromiseIsRejectedWithError(...expectValue): void
+ assertPromiseIsResolved(): void
+ assertPromiseIsResolvedWith(expectValue?: any): void
+}
+
+export function expect(actualValue?: any): Assert
+
+export class ArgumentMatchers {
+ static any;
+ static anyString;
+ static anyBoolean;
+ static anyNumber;
+ static anyObj;
+ static anyFunction;
+ static matchRegexs(Regex: RegExp): void
+}
+
+declare interface when {
+ afterReturn(value: any): any
+ afterReturnNothing(): undefined
+ afterAction(action: any): any
+ afterThrow(e_msg: string): string
+ (argMatchers?: any): when;
+}
+
+export interface VerificationMode {
+ times(count: Number): void
+ never(): void
+ once(): void
+ atLeast(count: Number): void
+ atMost(count: Number): void
+}
+
+export class MockKit {
+ constructor()
+ mockFunc(obj: Object, func: Function): Function
+ mockObject(obj: Object): Object
+ verify(methodName: String, argsArray: Array): VerificationMode
+ ignoreMock(obj: Object, func: Function): void
+ clear(obj: Object): void
+ clearAll(): void
+}
+
+export class SysTestKit {
+ static actionStart(tag: string): void
+ static actionEnd(tag: string): void
+ static existKeyword(keyword: string, timeout?: number): boolean
+}
+
+export class Hypium {
+ static setData(data: {[key: string]: any}): void
+ static setTimeConfig(systemTime: any)
+ static hypiumTest(abilityDelegator: any, abilityDelegatorArguments: any, testsuite: Function): void
+}
\ No newline at end of file
diff --git a/oh_modules/@ohos/hypium/index.ets b/oh_modules/@ohos/hypium/index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..355d006f5cd3e7f5e9d1a83374ad1dc0b588d1a0
--- /dev/null
+++ b/oh_modules/@ohos/hypium/index.ets
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Core from './src/main/core';
+import {ConfigService} from './src/main/module/config/configService'
+import {DEFAULT, TestType, Size, Level, TAG} from './src/main/Constant';
+import DataDriver from './src/main/module/config/DataDriver';
+import ExpectExtend from './src/main/module/assert/ExpectExtend';
+import OhReport from './src/main/module/report/OhReport';
+import SysTestKit from './src/main/module/kit/SysTestKit';
+import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from './src/main/interface';
+import {MockKit, when} from './src/main/module/mock/MockKit';
+import ArgumentMatchers from './src/main/module/mock/ArgumentMatchers';
+
+interface AbilityDelegatorArgs {
+ bundleName: string;
+ parameters: Object;
+ testCaseNames: string;
+ testRunnerClassName: string;
+}
+
+class Hypium {
+ static setData(data:Object) {
+ const core = Core.getInstance();
+ const dataDriver = new DataDriver({data});
+ core.addService('dataDriver', dataDriver);
+ }
+
+ static setTimeConfig(systemTime:Object) {
+ SysTestKit.systemTime = systemTime;
+ }
+
+ static hypiumTest(abilityDelegator:Object, abilityDelegatorArguments:AbilityDelegatorArgs, testsuite:Function) {
+ const core = Core.getInstance();
+ const expectExtend = new ExpectExtend({
+ id: 'extend'
+ });
+ core.addService('expect', expectExtend);
+ const ohReport = new OhReport({
+ delegator: abilityDelegator,
+ abilityDelegatorArguments: abilityDelegatorArguments
+ });
+ SysTestKit.delegator = abilityDelegator;
+ core.addService('report', ohReport);
+ core.init();
+ core.subscribeEvent('spec', ohReport);
+ core.subscribeEvent('suite', ohReport);
+ core.subscribeEvent('task', ohReport);
+ const configService:ConfigService = core.getDefaultService('config');
+ let testParameters:Object = null;
+ if (abilityDelegatorArguments !== null) {
+ testParameters = configService.translateParams(abilityDelegatorArguments.parameters);
+ }
+ console.info(`${TAG}parameters:${JSON.stringify(testParameters)}`);
+ configService.setConfig(testParameters);
+
+ testsuite();
+ core.execute(abilityDelegator);
+ }
+}
+
+export {
+ Hypium,
+ Core,
+ DEFAULT,
+ TestType,
+ Size,
+ Level,
+ DataDriver,
+ ExpectExtend,
+ OhReport,
+ SysTestKit,
+ describe, beforeAll, beforeEach, afterEach, afterAll, it, expect,
+ MockKit, when,
+ ArgumentMatchers
+};
\ No newline at end of file
diff --git a/oh_modules/@ohos/hypium/index.js b/oh_modules/@ohos/hypium/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..affc83beb4c94a3aa9440bd69069ebced10c9109
--- /dev/null
+++ b/oh_modules/@ohos/hypium/index.js
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License")
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Core from './src/main/core';
+import {DEFAULT, TestType, Size, Level, TAG} from './src/main/Constant';
+import DataDriver from './src/main/module/config/DataDriver';
+import ExpectExtend from './src/main/module/assert/ExpectExtend';
+import OhReport from './src/main/module/report/OhReport';
+import SysTestKit from './src/main/module/kit/SysTestKit';
+import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from './src/main/interface';
+import {MockKit, when} from './src/main/module/mock/MockKit';
+import ArgumentMatchers from './src/main/module/mock/ArgumentMatchers';
+
+class Hypium {
+ static setData(data) {
+ const core = Core.getInstance();
+ const dataDriver = new DataDriver({data});
+ core.addService('dataDriver', dataDriver);
+ }
+
+ static setTimeConfig(systemTime) {
+ SysTestKit.systemTime = systemTime;
+ }
+
+ static hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) {
+ const core = Core.getInstance();
+ const expectExtend = new ExpectExtend({
+ 'id': 'extend'
+ });
+ core.addService('expect', expectExtend);
+ const ohReport = new OhReport({
+ 'delegator': abilityDelegator,
+ 'abilityDelegatorArguments': abilityDelegatorArguments
+ });
+ SysTestKit.delegator = abilityDelegator;
+ core.addService('report', ohReport);
+ core.init();
+ core.subscribeEvent('spec', ohReport);
+ core.subscribeEvent('suite', ohReport);
+ core.subscribeEvent('task', ohReport);
+ const configService = core.getDefaultService('config');
+
+ let testParameters = {};
+ if (abilityDelegatorArguments !== null) {
+ testParameters = configService.translateParams(abilityDelegatorArguments.parameters);
+ }
+ console.info(`${TAG}parameters:${JSON.stringify(testParameters)}`);
+ configService.setConfig(testParameters);
+
+ testsuite();
+ core.execute(abilityDelegator);
+ }
+}
+
+export {
+ Hypium,
+ Core,
+ DEFAULT,
+ TestType,
+ Size,
+ Level,
+ DataDriver,
+ ExpectExtend,
+ OhReport,
+ SysTestKit,
+ describe, beforeAll, beforeEach, afterEach, afterAll, it, expect,
+ MockKit, when,
+ ArgumentMatchers
+};
\ No newline at end of file
diff --git a/oh_modules/@ohos/hypium/oh-package.json5 b/oh_modules/@ohos/hypium/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..586263cbcdd5006e495ee4176cdec5b96812dcae
--- /dev/null
+++ b/oh_modules/@ohos/hypium/oh-package.json5
@@ -0,0 +1,11 @@
+{
+ "name": "@ohos/hypium",
+ "version": "1.0.9",
+ "description": "A unit test framework for OpenHarmony application",
+ "main": "index.js",
+ "keywords": [],
+ "author": "huawei",
+ "license": "Apache-2.0",
+ "dependencies": {
+ }
+}
diff --git a/oh_modules/@ohos/hypium/src/main/Constant.js b/oh_modules/@ohos/hypium/src/main/Constant.js
new file mode 100644
index 0000000000000000000000000000000000000000..13f68499c8688027eb2dc49c6dc4028610ab480c
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/Constant.js
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * define the testcase type : TestType, Size , Level
+ */
+export const TAG = '[Hypium]';
+
+export const DEFAULT = 0B0000;
+
+export class TestType {
+ static FUNCTION = 0B1;
+ static PERFORMANCE = 0B1 << 1;
+ static POWER = 0B1 << 2;
+ static RELIABILITY = 0B1 << 3;
+ static SECURITY = 0B1 << 4;
+ static GLOBAL = 0B1 << 5;
+ static COMPATIBILITY = 0B1 << 6;
+ static USER = 0B1 << 7;
+ static STANDARD = 0B1 << 8;
+ static SAFETY = 0B1 << 9;
+ static RESILIENCE = 0B1 << 10;
+}
+
+export class Size {
+ static SMALLTEST = 0B1 << 16;
+ static MEDIUMTEST = 0B1 << 17;
+ static LARGETEST = 0B1 << 18;
+}
+
+export class Level {
+ static LEVEL0 = 0B1 << 24;
+ static LEVEL1 = 0B1 << 25;
+ static LEVEL2 = 0B1 << 26;
+ static LEVEL3 = 0B1 << 27;
+ static LEVEL4 = 0B1 << 28;
+}
diff --git a/oh_modules/@ohos/hypium/src/main/core.js b/oh_modules/@ohos/hypium/src/main/core.js
new file mode 100644
index 0000000000000000000000000000000000000000..cfcb5f17287208f5e6869b4248faf6c9093002d9
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/core.js
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {SuiteService, SpecService, ExpectService, ReportService} from './service';
+import {ConfigService} from './module/config/configService';
+import {SpecEvent, TaskEvent, SuiteEvent} from './event';
+
+/**
+ * core service for execute testcase.
+ */
+class Core {
+ static getInstance() {
+ if (!this.instance) {
+ this.instance = new Core();
+ }
+ return this.instance;
+ }
+
+ constructor() {
+ this.instance = null;
+ this.services = {
+ suite: {},
+ spec: {},
+ config: {},
+ expect: {},
+ log: {},
+ report: {}
+
+ };
+ this.events = {
+ suite: {},
+ spec: {},
+ task: {}
+ };
+ }
+
+ addService(name, service) {
+ let serviceObj = {};
+ if (!this.services[name]) {
+ this.services[name] = serviceObj;
+ } else {
+ serviceObj = this.services[name];
+ }
+ serviceObj[service.id] = service;
+ }
+
+ getDefaultService(name) {
+ return this.services[name].default;
+ }
+
+ getServices(name) {
+ return this.services[name];
+ }
+
+ registerEvent(serviceName, event) {
+ let eventObj = {};
+ if (!this.events[serviceName]) {
+ this.events[serviceName] = eventObj;
+ } else {
+ eventObj = this.events[serviceName];
+ }
+ eventObj[event.id] = event;
+ }
+
+ unRegisterEvent(serviceName, eventID) {
+ const eventObj = this.events[serviceName];
+ if (eventObj) {
+ delete eventObj[eventID];
+ }
+ }
+
+ subscribeEvent(serviceName, serviceObj) {
+ const eventObj = this.events[serviceName];
+ if (eventObj) {
+ for (const attr in eventObj) {
+ eventObj[attr]['subscribeEvent'](serviceObj);
+ }
+ }
+ }
+
+ async fireEvents(serviceName, eventName) {
+ const eventObj = this.events[serviceName];
+ if (!eventObj) {
+ return;
+ }
+ for (const attr in eventObj) {
+ await eventObj[attr][eventName]();
+ }
+ }
+
+ addToGlobal(apis) {
+ if (typeof globalThis !== 'undefined') {
+ for (let api in apis) {
+ globalThis[api] = apis[api];
+ }
+ }
+ for (const api in apis) {
+ this[api] = apis[api];
+ }
+ }
+
+ init() {
+ this.addService('suite', new SuiteService({id: 'default'}));
+ this.addService('spec', new SpecService({id: 'default'}));
+ this.addService('expect', new ExpectService({id: 'default'}));
+ this.addService('report', new ReportService({id: 'default'}));
+ this.addService('config', new ConfigService({id: 'default'}));
+ this.registerEvent('task', new TaskEvent({id: 'default', coreContext: this}));
+ this.registerEvent('suite', new SuiteEvent({id: 'default', coreContext: this}));
+ this.registerEvent('spec', new SpecEvent({id: 'default', coreContext: this}));
+ this.subscribeEvent('spec', this.getDefaultService('report'));
+ this.subscribeEvent('suite', this.getDefaultService('report'));
+ this.subscribeEvent('task', this.getDefaultService('report'));
+ const context = this;
+ for (const key in this.services) {
+ const serviceObj = this.services[key];
+ for (const serviceID in serviceObj) {
+ const service = serviceObj[serviceID];
+ service.init(context);
+
+ if (typeof service.apis !== 'function') {
+ continue;
+ }
+ const apis = service.apis();
+ if (apis) {
+ this.addToGlobal(apis);
+ }
+ }
+ }
+ }
+
+ execute(abilityDelegator) {
+ const suiteService = this.getDefaultService('suite');
+ const configService = this.getDefaultService('config');
+ if (configService['dryRun'] === 'true') {
+ (async function () {
+ await suiteService.dryRun(abilityDelegator);
+ })();
+ return;
+ }
+ setTimeout(() => {
+ suiteService.execute();
+ }, 10);
+ }
+}
+
+export default Core;
diff --git a/oh_modules/@ohos/hypium/src/main/event.js b/oh_modules/@ohos/hypium/src/main/event.js
new file mode 100644
index 0000000000000000000000000000000000000000..1333a1c483f9a2aa1c45e133b1d3cbbc7cdb8346
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/event.js
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class SpecEvent {
+ constructor(attr) {
+ this.id = attr.id;
+ this.coreContext = attr.context;
+ this.eventMonitors = [];
+ }
+
+ subscribeEvent(service) {
+ this.eventMonitors.push(service);
+ }
+
+ async specStart() {
+ for (const monitor of this.eventMonitors) {
+ await monitor['specStart']();
+ }
+ }
+
+ async specDone() {
+ for (const monitor of this.eventMonitors) {
+ await monitor['specDone']();
+ }
+ }
+}
+
+class SuiteEvent {
+ constructor(attr) {
+ this.id = attr.id;
+ this.suiteContext = attr.coreContext;
+ this.eventMonitors = [];
+ }
+
+ subscribeEvent(service) {
+ this.eventMonitors.push(service);
+ }
+
+ async suiteStart() {
+ for (const monitor of this.eventMonitors) {
+ await monitor['suiteStart']();
+ }
+ }
+
+ async suiteDone() {
+ for (const monitor of this.eventMonitors) {
+ await monitor['suiteDone']();
+ }
+ }
+}
+
+class TaskEvent {
+ constructor(attr) {
+ this.id = attr.id;
+ this.coreContext = attr.coreContext;
+ this.eventMonitors = [];
+ }
+
+ subscribeEvent(service) {
+ this.eventMonitors.push(service);
+ }
+
+ async taskStart() {
+ for (const monitor of this.eventMonitors) {
+ await monitor['taskStart']();
+ }
+ }
+
+ async taskDone() {
+ for (const monitor of this.eventMonitors) {
+ await monitor['taskDone']();
+ }
+ }
+
+ incorrectFormat() {
+ for (const monitor of this.eventMonitors) {
+ monitor['incorrectFormat']();
+ }
+ }
+}
+
+export {SpecEvent, TaskEvent, SuiteEvent};
diff --git a/oh_modules/@ohos/hypium/src/main/interface.js b/oh_modules/@ohos/hypium/src/main/interface.js
new file mode 100644
index 0000000000000000000000000000000000000000..40398c849d55cd76ab64fcba26899b547e2a3c97
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/interface.js
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Core from './core';
+
+const core = Core.getInstance();
+
+const describe = function (desc, func) {
+ return Reflect.has(core, 'describe') ? core.describe(desc, func) : (desc, func) => { };
+};
+const it = function (desc, filter, func) {
+ return Reflect.has(core, 'it') ? core.it(desc, filter, func) : (desc, filter, func) => { };
+};
+const beforeEach = function (func) {
+ return Reflect.has(core, 'beforeEach') ? core.beforeEach(func) : (func) => { };
+};
+const afterEach = function (func) {
+ return Reflect.has(core, 'afterEach') ? core.afterEach(func) : (func) => { };
+};
+const beforeAll = function (func) {
+ return Reflect.has(core, 'beforeAll') ? core.beforeAll(func) : (func) => { };
+};
+const afterAll = function (func) {
+ return Reflect.has(core, 'afterAll') ? core.afterAll(func) : (func) => { };
+};
+const expect = function (actualValue) {
+ return Reflect.has(core, 'expect') ? core.expect(actualValue) : (actualValue) => { };
+};
+
+export {
+ describe, it, beforeAll, beforeEach, afterEach, afterAll, expect
+};
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/ExpectExtend.js b/oh_modules/@ohos/hypium/src/main/module/assert/ExpectExtend.js
new file mode 100644
index 0000000000000000000000000000000000000000..d10d15e6f9955c6d04610101f8766c951ee1a35d
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/ExpectExtend.js
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import assertNull from './assertNull';
+import assertClose from './assertClose';
+import assertContain from './assertContain';
+import assertLess from './assertLess';
+import assertLarger from './assertLarger';
+import assertFail from './assertFail';
+import assertUndefined from './assertUndefined';
+import assertFalse from './assertFalse';
+import assertInstanceOf from './assertInstanceOf';
+import assertThrowError from './assertThrowError';
+import assertLargerOrEqual from './assertLargerOrEqual'
+import assertLessOrEqual from './assertLessOrEqual'
+import assertNaN from './assertNaN'
+import assertNegUnlimited from './assertNegUnlimited'
+import assertPosUnlimited from './assertPosUnlimited'
+import assertDeepEquals from './deepEquals/assertDeepEquals'
+import assertPromiseIsPending from './assertPromiseIsPending';
+import assertPromiseIsRejected from './assertPromiseIsRejected';
+import assertPromiseIsRejectedWith from './assertPromiseIsRejectedWith';
+import assertPromiseIsRejectedWithError from './assertPromiseIsRejectedWithError';
+import assertPromiseIsResolved from './assertPromiseIsResolved';
+import assertPromiseIsResolvedWith from './assertPromiseIsResolvedWith';
+class ExpectExtend {
+ constructor(attr) {
+ this.id = attr.id;
+ this.matchers = {};
+ }
+
+ extendsMatchers() {
+ this.matchers.assertNull = assertNull;
+ this.matchers.assertClose = assertClose;
+ this.matchers.assertContain = assertContain;
+ this.matchers.assertLess = assertLess;
+ this.matchers.assertLarger = assertLarger;
+ this.matchers.assertFail = assertFail;
+ this.matchers.assertUndefined = assertUndefined;
+ this.matchers.assertFalse = assertFalse;
+ this.matchers.assertInstanceOf = assertInstanceOf;
+ this.matchers.assertThrowError = assertThrowError;
+ this.matchers.assertLargerOrEqual = assertLargerOrEqual;
+ this.matchers.assertLessOrEqual = assertLessOrEqual;
+ this.matchers.assertNaN = assertNaN;
+ this.matchers.assertNegUnlimited = assertNegUnlimited;
+ this.matchers.assertPosUnlimited = assertPosUnlimited;
+ this.matchers.assertDeepEquals = assertDeepEquals;
+ this.matchers.assertPromiseIsPending = assertPromiseIsPending;
+ this.matchers.assertPromiseIsRejected = assertPromiseIsRejected;
+ this.matchers.assertPromiseIsRejectedWith = assertPromiseIsRejectedWith;
+ this.matchers.assertPromiseIsRejectedWithError = assertPromiseIsRejectedWithError;
+ this.matchers.assertPromiseIsResolved = assertPromiseIsResolved;
+ this.matchers.assertPromiseIsResolvedWith = assertPromiseIsResolvedWith;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ this.extendsMatchers();
+ const expectService = this.coreContext.getDefaultService('expect');
+ expectService.addMatchers(this.matchers);
+ }
+
+ apis() {
+ return {
+ 'expect': function (actualValue) {
+ return this.coreContext.getDefaultService('expect').expect(actualValue);
+ }
+ };
+ }
+}
+
+export default ExpectExtend;
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertClose.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertClose.js
new file mode 100644
index 0000000000000000000000000000000000000000..63635bea5bf1298776de565260e0e0babae56857
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertClose.js
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertClose(actualValue, expected) {
+ console.log('expected:' + expected[0] + ',precision:' + expected[1]);
+ if (actualValue === null && expected[0] === null) {
+ throw new Error('actualValue and expected can not be both null!!!');
+ }
+ let result;
+ let diff = Math.abs(expected[0] - actualValue);
+ let actualAbs = Math.abs(actualValue);
+ if ((actualAbs - 0) === 0) {
+ if ((diff - 0) === 0) {
+ result = true;
+ } else {
+ result = false;
+ }
+ } else if (diff / actualAbs < expected[1]) {
+ result = true;
+ } else {
+ result = false;
+ }
+ return {
+ pass: result,
+ message: '|' + actualValue + ' - ' + expected[0] + '|/' + actualValue + ' is not less than ' + expected[1]
+ };
+}
+
+export default assertClose;
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertContain.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertContain.js
new file mode 100644
index 0000000000000000000000000000000000000000..7fba0d9755503e5e926f6c1a4e425e0d1cf47570
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertContain.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertContain(actualValue, expect) {
+ let result = false;
+ if (Object.prototype.toString.call(actualValue).indexOf('Array')) {
+ for (let i in actualValue) {
+ if (actualValue[i] == expect[0]) {
+ result = true;
+ }
+ }
+ }
+ let type = Object.prototype.toString.call(actualValue);
+ if (type === '[object String]') {
+ result = actualValue.indexOf(expect[0]) >= 0;
+ }
+ return {
+ pass: result,
+ message: 'expect false, ' + actualValue + ' do not have ' + expect[0]
+ };
+}
+
+export default assertContain;
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertFail.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertFail.js
new file mode 100644
index 0000000000000000000000000000000000000000..8ab4ac5caef712c75c4eac49dfbbb91d33669d9a
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertFail.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertFail() {
+ return {
+ pass: false,
+ message: 'fail '
+ };
+}
+
+export default assertFail;
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertFalse.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertFalse.js
new file mode 100644
index 0000000000000000000000000000000000000000..c5008e94f4b2ce13ed35b604811793c76b542347
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertFalse.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertFalse(actualValue) {
+ return {
+ pass: (actualValue) === false,
+ message: 'expect false, actualValue is ' + actualValue
+ };
+}
+
+export default assertFalse;
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertInstanceOf.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertInstanceOf.js
new file mode 100644
index 0000000000000000000000000000000000000000..1e11b93f7251c67f5455c5007cd7be268aa53b32
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertInstanceOf.js
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertInstanceOf(actualValue, expected) {
+ if (Object.prototype.toString.call(actualValue) == '[object ' + expected[0] + ']') {
+ return {
+ pass: true
+ };
+ } else {
+ return {
+ pass: false,
+ message: actualValue + ' is ' + Object.prototype.toString.call(actualValue) + 'not ' + expected[0]
+ };
+ }
+}
+
+export default assertInstanceOf;
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertLarger.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertLarger.js
new file mode 100644
index 0000000000000000000000000000000000000000..a74f4a8cedaf3add9c2dc2d3799081a83198732f
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertLarger.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertLarger(actualValue, expected) {
+ return {
+ pass: (actualValue) > expected[0],
+ message: (actualValue) + ' is not larger than ' + expected[0]
+ };
+}
+
+export default assertLarger;
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertLargerOrEqual.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertLargerOrEqual.js
new file mode 100644
index 0000000000000000000000000000000000000000..e847e6c217364b7f69c173c66fb98d10efc45ef1
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertLargerOrEqual.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertLargerOrEqual(actualValue, expected) {
+ return {
+ pass: (actualValue) >= expected[0],
+ message: (actualValue) + ' is not larger than ' + expected[0]
+ };
+}
+
+export default assertLargerOrEqual;
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertLess.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertLess.js
new file mode 100644
index 0000000000000000000000000000000000000000..17e84b0abaeb20804048a5a15c19e0603634846d
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertLess.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertLess(actualValue, expected) {
+ return {
+ pass: (actualValue) < expected[0],
+ message: (actualValue) + ' is not less than ' + expected[0]
+ };
+}
+
+export default assertLess;
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertLessOrEqual.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertLessOrEqual.js
new file mode 100644
index 0000000000000000000000000000000000000000..f754f97ffa9d24e7852efe2423a1dd35d448af82
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertLessOrEqual.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertLessOrEqual(actualValue, expected) {
+ return {
+ pass: (actualValue) <= expected[0],
+ message: (actualValue) + ' is not less than ' + expected[0]
+ };
+}
+
+export default assertLessOrEqual;
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertNaN.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertNaN.js
new file mode 100644
index 0000000000000000000000000000000000000000..8d45d6a93b86c5ed325a68b32ff014835993a58e
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertNaN.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertNaN(actualValue) {
+ return {
+ pass: actualValue !== actualValue,
+ message: 'expect NaN, actualValue is ' + actualValue
+ };
+}
+
+export default assertNaN;
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertNegUnlimited.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertNegUnlimited.js
new file mode 100644
index 0000000000000000000000000000000000000000..ceac555afc826e057970e6cfe9c73b322c672aa2
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertNegUnlimited.js
@@ -0,0 +1,23 @@
+/*
+* Copyright (c) 2022 Huawei Device Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+function assertNegUnlimited(actualValue) {
+ return {
+ pass: actualValue === Number.NEGATIVE_INFINITY,
+ message: 'Expected actualValue not to be -Infinity. actualValue is,' + actualValue
+ };
+}
+
+export default assertNegUnlimited;
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertNull.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertNull.js
new file mode 100644
index 0000000000000000000000000000000000000000..53a7bad827323a98d3302a4e7eea679551b459c5
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertNull.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertNull(actualValue) {
+ return {
+ pass: (actualValue) === null,
+ message: 'expect null, actualValue is ' + (actualValue)
+ };
+}
+
+export default assertNull;
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertPosUnlimited.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertPosUnlimited.js
new file mode 100644
index 0000000000000000000000000000000000000000..6e68c0e2b6c499f4dc3dd56c13e9ea1073a3c54c
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertPosUnlimited.js
@@ -0,0 +1,23 @@
+/*
+* Copyright (c) 2022 Huawei Device Co., Ltd.
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+function assertPosUnlimited(actualValue) {
+ return {
+ pass: actualValue === Number.POSITIVE_INFINITY,
+ message: 'Expected actualValue is POSITIVE_INFINITY. actualValue is,' + actualValue
+ };
+}
+
+export default assertPosUnlimited;
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsPending.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsPending.js
new file mode 100644
index 0000000000000000000000000000000000000000..7e2ca2ce14d50c39554fc1157d6d4eb9329d5c39
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsPending.js
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import isPromiseLike from './isPromiseLike';
+
+function assertPromiseIsPending(actualPromise) {
+ if (!isPromiseLike(actualPromise)) {
+ return Promise.reject().then(function () {
+ }, function () {
+ return {pass: false, message: 'Expected not be called on a promise.'};
+ });
+ }
+ const helper = {};
+ return Promise.race([actualPromise, Promise.resolve(helper)]).then(
+ function (got) {
+ return helper === got ? {pass: true, message: 'actualValue is isPending'}
+ : {
+ pass: false,
+ message: 'expect isPending, actualValue is resolve'
+ };
+ },
+ function () {
+ return {
+ pass: false
+ , message: 'expect isPending, actualValue is reject'
+ };
+ });
+}
+
+export default assertPromiseIsPending;
\ No newline at end of file
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejected.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejected.js
new file mode 100644
index 0000000000000000000000000000000000000000..eb8e65c7d70d5750a9ccebb55c2cf5049cf144fc
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejected.js
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import isPromiseLike from './isPromiseLike';
+
+function assertPromiseIsRejected(actualPromise) {
+ if (!isPromiseLike(actualPromise)) {
+ return Promise.reject().then(function () {
+ }, function () {
+ return {pass: false, message: 'Expected not be called on a promise.'};
+ });
+ }
+ const helper = {};
+ return Promise.race([actualPromise, Promise.resolve(helper)]).then(
+ function (got) {
+ return {
+ pass: false,
+ message: 'expect isRejected, but actualValue is '
+ + (helper === got ? 'isPending' : 'resolve')
+ };
+ },
+ function () {
+ return {pass: true, message: 'actualValue is isRejected'};
+ }
+ );
+}
+
+export default assertPromiseIsRejected;
\ No newline at end of file
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWith.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWith.js
new file mode 100644
index 0000000000000000000000000000000000000000..48eaf7859279a70ea2ad85509296b5da1c7b69f9
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWith.js
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import isPromiseLike from './isPromiseLike';
+
+function assertPromiseIsRejectedWith(actualPromise, expectedValue) {
+
+ if (!isPromiseLike(actualPromise)) {
+ return Promise.reject().then(function () {
+ }, function () {
+ return {pass: false, message: 'Expected not be called on a promise.'};
+ });
+ }
+
+ function tips(passed) {
+ return ('Expected a promise ' + (passed ? 'not ' : '') +
+ 'to be rejected with ' + JSON.stringify(expectedValue[0]));
+ }
+
+ const helper = {};
+ return Promise.race([actualPromise, Promise.resolve(helper)]).then(
+ function (got) {
+ return {
+ pass: false,
+ message: tips(false) + ' but actualValue is '
+ + (helper === got ? 'isPending' : 'resolve')
+ };
+ },
+ function (actualValue) {
+ if (JSON.stringify(actualValue) == JSON.stringify(expectedValue[0])) {
+ return {
+ pass: true,
+ message: 'actualValue was rejected with ' + JSON.stringify(actualValue) + '.'
+ };
+ } else {
+ return {
+ pass: false,
+ message: tips(false) + ' but it was rejected with ' + JSON.stringify(actualValue) + '.'
+ };
+ }
+ }
+ );
+}
+
+export default assertPromiseIsRejectedWith;
\ No newline at end of file
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWithError.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWithError.js
new file mode 100644
index 0000000000000000000000000000000000000000..20f236fc11dd66f270322efa12a1b3f6b543407c
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWithError.js
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import isPromiseLike from './isPromiseLike';
+
+function assertPromiseIsRejectedWithError(actualPromise, expectedValue) {
+ if (!isPromiseLike(actualPromise)) {
+ return Promise.reject().then(function () {
+ }, function () {
+ return {pass: false, message: 'Expected not be called on a promise.'};
+ });
+ }
+ const helper = {};
+ return Promise.race([actualPromise, Promise.resolve(helper)]).then(
+ function (got) {
+ return {
+ pass: false,
+ message: 'Expected a promise to be rejected but actualValue is '
+ + (helper === got ? 'isPending' : 'resolve')
+ };
+ },
+ function (actualValue) {
+ return matchError(actualValue, expectedValue);
+ }
+ );
+
+}
+
+function matchError(actualValue, expectedValue) {
+ if (expectedValue.length == 1 && typeof expectedValue[0] === 'function') {
+ if (expectedValue[0].name === actualValue.__proto__.name) {
+ return {pass: true, message: 'actual error type is ' + actualValue.name + '.'};
+ }
+ return {pass: false, message: `except error type is ${expectedValue[0].name},but actual is ${actualValue.name}.`};
+ }
+
+ if (expectedValue.length == 1 && typeof expectedValue[0] === 'string') {
+ if (expectedValue[0] === actualValue.message) {
+ return {pass: true, message: `actual error message is ${actualValue.message}.`};
+ }
+ return {pass: false, message: `except error message ${expectedValue[0]},but actual is ${actualValue.message}.`};
+ }
+
+ if (expectedValue.length == 1) {
+ return {pass: false, message: 'When only one parameter, it should be error type or error message.'};
+ }
+
+ if (expectedValue.length == 2 && typeof expectedValue[0] === 'function' && expectedValue[0].name === actualValue.name) {
+ if (typeof expectedValue[1] === 'string' && actualValue.message === expectedValue[1]) {
+ return {pass: true, message: 'actual error message is ' + actualValue.message + '.'};
+ }
+ return {pass: false, message: `except error message is ${expectedValue[1]},but actual is ${actualValue.message}.`};
+ }
+
+ if (expectedValue.length == 2 && typeof expectedValue[0] === 'function' && expectedValue[0].name !== actualValue.name) {
+ if (typeof expectedValue[1] === 'string' && actualValue.message === expectedValue[1]) {
+ return {pass: false, message: `except error type is ${expectedValue[0].name},but actual is ${actualValue.name}.`};
+ }
+ return {pass: false, message: 'except error type and message are incorrect.'};
+ }
+ if (expectedValue.length > 2) {
+ return {pass: false, message: 'Up to two parameters are supported.'};
+ }
+}
+
+export default assertPromiseIsRejectedWithError;
\ No newline at end of file
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolved.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolved.js
new file mode 100644
index 0000000000000000000000000000000000000000..855426ca79e5002428e53d4fcb5f843cdf7119f7
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolved.js
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import isPromiseLike from './isPromiseLike';
+
+function assertPromiseIsResolved(actualPromise) {
+ if (!isPromiseLike(actualPromise)) {
+ return Promise.reject().then(function () {
+ }, function () {
+ return {pass: false, message: 'Expected not be called on a promise.'};
+ });
+ }
+
+ const helper = {};
+ return Promise.race([actualPromise, Promise.resolve(helper)]).then(
+ function (got) {
+ return helper === got ? {
+ pass: false,
+ message: 'expect resolve, actualValue is isPending'
+ }
+ : {pass: true, message: 'actualValue is isResolved'};
+ },
+ function (rej) {
+ return {
+ pass: false,
+ message: 'Expected a promise to be resolved but it was ' +
+ 'rejected with ' + JSON.stringify(rej) + '.'
+ };
+ }
+ );
+}
+
+export default assertPromiseIsResolved;
\ No newline at end of file
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolvedWith.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolvedWith.js
new file mode 100644
index 0000000000000000000000000000000000000000..d5eb01e32491b281a1e1d650a307723253a61e39
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolvedWith.js
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import isPromiseLike from './isPromiseLike';
+
+function assertPromiseIsResolvedWith(actualPromise, expectedValue) {
+ if (!isPromiseLike(actualPromise)) {
+ return Promise.reject().then(function () {
+ }, function () {
+ return {pass: false, message: 'Expected not be called on a promise.'};
+ });
+ }
+
+ function tips(passed) {
+ return (
+ 'Expected a promise ' + (passed ? 'not ' : '') +
+ 'to be resolved with ' + JSON.stringify(expectedValue[0]));
+ }
+
+ const helper = {};
+ return Promise.race([actualPromise, Promise.resolve(helper)]).then(
+ function (got) {
+ if (helper === got) {
+ return {pass: false, message: 'expect resolve, actualValue is isPending'};
+ }
+ if (JSON.stringify(got) == JSON.stringify(expectedValue[0])) {
+ return {
+ pass: true,
+ message: 'actualValue was resolved with ' + JSON.stringify(got) + '.'
+ };
+ }
+ return {
+ pass: false,
+ message: tips(false) + ' but it was resolved with ' +
+ JSON.stringify(got) + '.'
+ };
+ },
+ function (rej) {
+ return {
+ pass: false,
+ message: tips(false) + ' but it was rejected with ' + JSON.stringify(rej) + '.'
+ };
+ }
+ );
+}
+
+export default assertPromiseIsResolvedWith;
\ No newline at end of file
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertThrowError.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertThrowError.js
new file mode 100644
index 0000000000000000000000000000000000000000..749cab0daee3f156909f60c9375146c23d7aa322
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertThrowError.js
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertThrowError(actualValue, expected) {
+ let result = false;
+ let err;
+ if (typeof actualValue !== 'function') {
+ throw new Error('actualValue is not a function');
+ }
+ try {
+ actualValue();
+ return {
+ pass: result,
+ message: ' An error is not thrown while it is expected!'
+ };
+ } catch (e) {
+ err = e;
+ }
+
+ if (err instanceof Error) {
+ console.log(err.message);
+ if (err.message == expected[0]) {
+ result = true;
+ }
+ }
+ return {
+ pass: result,
+ message: 'expected throw failed , ' + err.message + ' is not ' + expected[0]
+ };
+}
+
+export default assertThrowError;
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/assertUndefined.js b/oh_modules/@ohos/hypium/src/main/module/assert/assertUndefined.js
new file mode 100644
index 0000000000000000000000000000000000000000..61f092d715dd1630297518b59ff13ef0940991e1
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/assertUndefined.js
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function assertUndefined(actualValue) {
+ return {
+ pass: undefined === (actualValue),
+ message: 'expect Undefined, actualValue is ' + (actualValue)
+ };
+}
+
+export default assertUndefined;
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/DeepTypeUtils.js b/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/DeepTypeUtils.js
new file mode 100644
index 0000000000000000000000000000000000000000..627fb3b3ae7e315808b5ee2927d4bfbf17cc64b2
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/DeepTypeUtils.js
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class DeepTypeUtils {
+ static getType_(value) {
+ return Object.prototype.toString.apply(value);
+ }
+ static isA_(typeName, value) {
+ return this.getType_(value) === '[object ' + typeName + ']';
+ }
+ static isAsymmetricEqualityTester_(obj) {
+ return obj ? this.isA_('Function', obj.asymmetricMatch) : false;
+ }
+
+ /**
+ * 是否是function
+ * @param value
+ */
+ static isFunction_(value) {
+ return this.isA_('Function', value);
+ }
+
+ /**
+ * 是否是undefined
+ * @param obj
+ */
+ static isUndefined(obj) {
+ return obj === void 0;
+ }
+
+ /**
+ * 是否是Node
+ * @param obj
+ */
+ static isDomNode(obj) {
+ return obj !== null &&
+ typeof obj === 'object' &&
+ typeof obj.nodeType === 'number' &&
+ typeof obj.nodeName === 'string';
+ }
+
+ /**
+ * 是否是promise对象
+ * @param obj
+ */
+ static isPromise (obj) {
+ return !!obj && obj.constructor === Promise;
+ };
+ /**
+ * 是否是map对象
+ * @param obj
+ */
+ static isMap(obj) {
+ return (
+ obj !== null &&
+ typeof obj !== 'undefined' &&
+ obj.constructor === Map
+ );
+ }
+
+ /**
+ * 是否是set对象
+ * @param obj 对象
+ */
+ static isSet(obj) {
+ return (
+ obj !== null &&
+ typeof obj !== 'undefined' &&
+ obj.constructor === Set
+ );
+ }
+
+ /**
+ * 对象是否有key属性
+ * @param obj 对象
+ * @param key 对象属性名称
+ */
+ static has(obj, key) {
+ return Object.prototype.hasOwnProperty.call(obj, key);
+ }
+
+ /**
+ * 获取对象的自有属性
+ * @param obj 对象
+ * @param isArray 是否是数组,[object Array]
+ */
+ static keys(obj, isArray) {
+ const extraKeys = [];
+ // 获取对象所有属性
+ const allKeys = this.getAllKeys(obj);
+ if (!isArray) {
+ return allKeys;
+ }
+ if (allKeys.length === 0) {
+ return allKeys;
+ }
+ for (const k of allKeys) {
+ if (typeof k === 'symbol' || !/^[0-9]+$/.test(k)) {
+ extraKeys.push(k);
+ }
+ }
+ return extraKeys;
+ }
+
+ /**
+ * 获取obj对象的所有属性
+ * @param obj obj对象
+ */
+ static getAllKeys(obj) {
+ const keys = [];
+ for (let key in obj) {
+ if(this.has(obj, key)) {
+ keys.push(key);
+ }
+ }
+ const symbols = Object.getOwnPropertySymbols(obj);
+ for (const sym of symbols) {
+ if (obj.propertyIsEnumerable(sym)) {
+ keys.push(sym);
+ }
+ }
+ return keys;
+ }
+
+}
+export default DeepTypeUtils;
\ No newline at end of file
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/assertDeepEquals.js b/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/assertDeepEquals.js
new file mode 100644
index 0000000000000000000000000000000000000000..482e28e6af45482f8c2d9d0f61130730b07eba70
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/assertDeepEquals.js
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import DeepTypeUtils from './DeepTypeUtils'
+function assertDeepEquals(actualValue, expected) {
+ console.log('actualValue:' + actualValue + ',expected:' + expected[0]);
+ let result = eq(actualValue, expected[0],[], [])
+ let msg = logMsg(actualValue, expected[0]);
+ return {
+ pass: result,
+ message: msg
+ };
+}
+
+/**
+ * 获取失败显示日志
+ * @param actualValue 实际对象
+ * @param expected 期待比较对象
+ */
+function logMsg(actualValue, expected) {
+ // 获取a的对象名称
+ const aClassName = Object.prototype.toString.call(actualValue);
+ const bClassName = Object.prototype.toString.call(expected);
+ let actualMsg;
+ let expectMsg;
+ if(aClassName == "[object Function]") {
+ actualMsg = "actualValue Function"
+ }else if(aClassName == "[object Promise]") {
+ actualMsg = "actualValue Promise"
+ }else if(aClassName == "[object Set]" || aClassName == "[object Map]") {
+ actualMsg = JSON.stringify(Array.from(actualValue));;
+ }else if(aClassName == "[object RegExp]") {
+ actualMsg = JSON.stringify(actualValue.source.replace("\\",""));;
+ }else if(aClassName == "[object BigInt]") {
+ actualMsg = actualValue;
+ }
+ else{
+ actualMsg = JSON.stringify(actualValue);
+ }
+ if(bClassName == "[object Function]") {
+ expectMsg = "expected Function"
+ }else if(bClassName == "[object Promise]") {
+ expectMsg = "expected Promise"
+ }else if(bClassName == "[object Set]" || bClassName == "[object Map]") {
+ expectMsg = JSON.stringify(Array.from(expected));
+ }else if(bClassName == "[object RegExp]") {
+ expectMsg = JSON.stringify(expected.source.replace("\\",""));;
+ }else if(bClassName == "[object BigInt]") {
+ expectMsg = expected;
+ }
+ else{
+ expectMsg = JSON.stringify(expected);
+ }
+ return actualMsg + " is not deep equal " + expectMsg;
+}
+
+function eq(a, b, aStack, bStack) {
+ let result = true;
+ console.log('a is:' + a + ',b is:' + b);
+ const asymmetricResult = asymmetricMatch_(a,b);
+ if (!DeepTypeUtils.isUndefined(asymmetricResult)) {
+ return asymmetricResult;
+ }
+
+ if (a instanceof Error && b instanceof Error) {
+ result = a.message == b.message;
+ return result;
+ }
+
+ if (a === b) {
+ result = a !== 0 || 1 / a == 1 / b;
+ return result;
+ }
+
+ if (a === null || b === null) {
+ result = a === b;
+ return result;
+ }
+ // 获取a的对象名称
+ const aClassName = Object.prototype.toString.call(a);
+ const bClassName = Object.prototype.toString.call(b);
+ console.log('aClassName is:' + aClassName);
+ console.log('bClassName is:' + bClassName);
+ // 不同类型不同对象
+ if (aClassName != bClassName) {
+ return false;
+ }
+ // 俩个string对象
+ if(aClassName === '[object String]') {
+ result = a == String(b);
+ return result;
+ }
+ // 俩个Number对象
+ if(aClassName === '[object Number]') {
+ result = a != +a ? b != +b : a === 0 && b === 0 ? 1 / a == 1 / b : a == +b;
+ return result;
+ }
+
+ if(aClassName === '[object Date]' || aClassName === '[object Boolean]') {
+ result = +a == +b;
+ return result;
+ }
+
+ // 数组
+ if(aClassName === '[object ArrayBuffer]') {
+ return eq(new Uint8Array(a), new Uint8Array(b), aStack, bStack);
+ }
+
+ // 正则表达式
+ if(aClassName === '[object RegExp]') {
+ return (
+ a.source == b.source &&
+ a.global == b.global &&
+ a.multiline == b.multiline &&
+ a.ignoreCase == b.ignoreCase
+ );
+ }
+
+ if (typeof a != 'object' || typeof b != 'object') {
+ return false;
+ }
+
+ const aIsDomNode = DeepTypeUtils.isDomNode(a);
+ const bIsDomNode = DeepTypeUtils.isDomNode(b);
+ if (aIsDomNode && bIsDomNode) {
+ // At first try to use DOM3 method isEqualNode
+ result = a.isEqualNode(b);
+ return result;
+ }
+ if (aIsDomNode || bIsDomNode) {
+ return false;
+ }
+ const aIsPromise = DeepTypeUtils.isPromise(a);
+ const bIsPromise = DeepTypeUtils.isPromise(b);
+ if (aIsPromise && bIsPromise) {
+ return a === b;
+ }
+ let length = aStack.length;
+ while (length--) {
+ if (aStack[length] == a) {
+ return bStack[length] == b;
+ }
+ }
+ aStack.push(a);
+ bStack.push(b);
+ let size = 0;
+
+ // 都是数组
+ if(aClassName == '[object Array]') {
+ const aLength = a.length;
+ const bLength = b.length;
+ if (aLength !== bLength) {
+ // 数组长度不同,不是同一个对象
+ return false;
+ }
+ for (let i = 0; i < aLength || i < bLength; i++) {
+ // 递归每一个元素是否相同
+ result = eq(i < aLength ? a[i] : void 0, i < bLength ? b[i] : void 0, aStack, bStack) && result;
+ }
+ if (!result) {
+ return false;
+ }
+ } else if(DeepTypeUtils.isMap(a) && DeepTypeUtils.isMap(b)) {
+ if (a.size != b.size) {
+ return false;
+ }
+ const keysA = [];
+ const keysB = [];
+ a.forEach(function(valueA, keyA) {
+ keysA.push(keyA);
+ });
+ b.forEach(function(valueB, keyB) {
+ keysB.push(keyB);
+ });
+ const mapKeys = [keysA, keysB];
+ const cmpKeys = [keysB, keysA];
+ for (let i = 0; result && i < mapKeys.length; i++) {
+ const mapIter = mapKeys[i];
+ const cmpIter = cmpKeys[i];
+
+ for (let j = 0; result && j < mapIter.length; j++) {
+ const mapKey = mapIter[j];
+ const cmpKey = cmpIter[j];
+ const mapValueA = a.get(mapKey);
+ let mapValueB;
+ if (
+ DeepTypeUtils.isAsymmetricEqualityTester_(mapKey) ||
+ (DeepTypeUtils.isAsymmetricEqualityTester_(cmpKey) &&
+ eq(mapKey, cmpKey))
+ ) {
+ mapValueB = b.get(cmpKey);
+ } else {
+ mapValueB = b.get(mapKey);
+ }
+ result = eq(mapValueA, mapValueB, aStack, bStack);
+ }
+ }
+ if (!result) {
+ return false;
+ }
+ } else if(DeepTypeUtils.isSet(a) && DeepTypeUtils.isSet(b)) {
+ if (a.size != b.size) {
+ return false;
+ }
+ const valuesA = [];
+ a.forEach(function(valueA) {
+ valuesA.push(valueA);
+ });
+ const valuesB = [];
+ b.forEach(function(valueB) {
+ valuesB.push(valueB);
+ });
+ const setPairs = [[valuesA, valuesB], [valuesB, valuesA]];
+ const stackPairs = [[aStack, bStack], [bStack, aStack]];
+ for (let i = 0; result && i < setPairs.length; i++) {
+ const baseValues = setPairs[i][0];
+ const otherValues = setPairs[i][1];
+ const baseStack = stackPairs[i][0];
+ const otherStack = stackPairs[i][1];
+ for (const baseValue of baseValues) {
+ let found = false;
+ for (let j = 0; !found && j < otherValues.length; j++) {
+ const otherValue = otherValues[j];
+ const prevStackSize = baseStack.length;
+ // 深度比较对象
+ found = eq(baseValue, otherValue, baseStack, otherStack);
+ if (!found && prevStackSize !== baseStack.length) {
+ baseStack.splice(prevStackSize);
+ otherStack.splice(prevStackSize);
+ }
+ }
+ result = result && found;
+ }
+ }
+ if (!result) {
+ return false;
+ }
+ } else {
+ const aCtor = a.constructor,
+ bCtor = b.constructor;
+ if (
+ aCtor !== bCtor &&
+ DeepTypeUtils.isFunction_(aCtor) &&
+ DeepTypeUtils.isFunction_(bCtor) &&
+ a instanceof aCtor &&
+ b instanceof bCtor &&
+ !(aCtor instanceof aCtor && bCtor instanceof bCtor)
+ ) {
+ return false;
+ }
+ }
+
+ // 获取对象所有的属性集合
+ const aKeys = DeepTypeUtils.keys(a, aClassName == '[object Array]');
+ size = aKeys.length;
+
+ // 俩个对象属性长度不一致, 俩对象不相同
+ if (DeepTypeUtils.keys(b, bClassName == '[object Array]').length !== size) {
+ return false;
+ }
+
+ // 俩对象属性数量相同, 递归比较每个属性值得值
+ for (const key of aKeys) {
+ console.log('key is:' + key);
+ // b 没有 key 属性
+ if(!DeepTypeUtils.has(b, key)) {
+ result = false;
+ continue;
+ }
+ if (!eq(a[key], b[key], aStack, bStack)) {
+ result = false;
+ }
+ }
+ if (!result) {
+ return false;
+ }
+ aStack.pop();
+ bStack.pop();
+ return result;
+}
+
+function asymmetricMatch_(a, b) {
+ const asymmetricA = DeepTypeUtils.isAsymmetricEqualityTester_(a);
+ const asymmetricB = DeepTypeUtils.isAsymmetricEqualityTester_(b);
+
+ if (asymmetricA === asymmetricB) {
+ return undefined;
+ }
+
+}
+
+/**
+ * 获取对象的自有属性
+ *
+ * @param obj 对象
+ * @param isArray 是否是一个数组
+ */
+function keys(obj, isArray) {
+ const keys = [];
+
+}
+
+export default assertDeepEquals;
diff --git a/oh_modules/@ohos/hypium/src/main/module/assert/isPromiseLike.js b/oh_modules/@ohos/hypium/src/main/module/assert/isPromiseLike.js
new file mode 100644
index 0000000000000000000000000000000000000000..015ab19a2a0c4872d7cb490b61f8e1dd6a8ac90b
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/assert/isPromiseLike.js
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+function isPromiseLike(obj) {
+ return !!obj && isFunction_(obj.then);
+}
+
+function isFunction_(value) {
+ return isA_('Function', value);
+}
+
+function isA_(typeName, value) {
+ return getType_(value) === '[object ' + typeName + ']';
+}
+
+function getType_(value) {
+ return Object.prototype.toString.apply(value);
+}
+
+export default isPromiseLike;
diff --git a/oh_modules/@ohos/hypium/src/main/module/config/DataDriver.js b/oh_modules/@ohos/hypium/src/main/module/config/DataDriver.js
new file mode 100644
index 0000000000000000000000000000000000000000..639dffc9cdb912f1f33a6ccb61868c9ed7c695bf
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/config/DataDriver.js
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const SUITES_KEY = 'suites';
+const SPECS_KEY = 'items';
+const DESCRIBE_KEY = 'describe';
+const IT_KEY = 'it';
+const PARAMS_KEY = 'params';
+const STRESS_KEY = 'stress';
+
+class ObjectUtils {
+ static get(object, name, defaultValue) {
+ let result = defaultValue;
+ for (const key in object) {
+ if (key === name) {
+ return object[key];
+ }
+ }
+ return result;
+ }
+
+ static has(object, key) {
+ return Object.prototype.hasOwnProperty.call(object, key);
+ }
+}
+
+class DataDriver {
+ constructor(attr) {
+ this.id = 'dataDriver';
+ this.data = attr.data || {};
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ this.suiteService = this.coreContext.getDefaultService('suite');
+ this.specService = this.coreContext.getDefaultService('spec');
+ }
+
+ getSpecParams() {
+ let specParams = [];
+ let suiteDesc = this.suiteService.getCurrentRunningSuite().description;
+ let specDesc = this.specService.getCurrentRunningSpec().description;
+ let suites = ObjectUtils.get(this.data, SUITES_KEY, []);
+ for (const suiteItem of suites) {
+ let describeValue = ObjectUtils.get(suiteItem, DESCRIBE_KEY, '');
+ if (ObjectUtils.has(suiteItem, DESCRIBE_KEY) && (typeof describeValue === 'object') && describeValue.constructor === Array && describeValue.includes(suiteDesc)) {
+ let specs = ObjectUtils.get(suiteItem, SPECS_KEY, []);
+ for (const specItem of specs) {
+ if (ObjectUtils.has(specItem, IT_KEY) && ObjectUtils.get(specItem, IT_KEY) === specDesc) {
+ return ObjectUtils.get(specItem, PARAMS_KEY, specParams);
+ }
+ }
+ }
+ }
+ return specParams;
+ }
+
+ getSuiteParams() {
+ let suiteParams = {};
+ let suiteDesc = this.suiteService.getCurrentRunningSuite().description;
+ let suites = ObjectUtils.get(this.data, SUITES_KEY, []);
+ for (const suiteItem of suites) {
+ let describeValue = ObjectUtils.get(suiteItem, DESCRIBE_KEY, []);
+ if (ObjectUtils.has(suiteItem, DESCRIBE_KEY) && (typeof describeValue === 'object') && describeValue.constructor === Array && describeValue.includes(suiteDesc)) {
+ suiteParams = Object.assign({}, suiteParams, ObjectUtils.get(suiteItem, PARAMS_KEY, suiteParams));
+ }
+ }
+ return suiteParams;
+ }
+
+ getSpecStress(specDesc) {
+ let stress = 1;
+ let suiteDesc = this.suiteService.getCurrentRunningSuite().description;
+ let suites = ObjectUtils.get(this.data, SUITES_KEY, []);
+ for (const suiteItem of suites) {
+ let describeValue = ObjectUtils.get(suiteItem, DESCRIBE_KEY, '');
+ if (ObjectUtils.has(suiteItem, DESCRIBE_KEY) && (typeof describeValue === 'object') && describeValue.constructor === Array && describeValue.includes(suiteDesc)) {
+ let specs = ObjectUtils.get(suiteItem, SPECS_KEY, []);
+ for (const specItem of specs) {
+ if (ObjectUtils.has(specItem, IT_KEY) && ObjectUtils.get(specItem, IT_KEY) === specDesc) {
+ let tempStress = ObjectUtils.get(specItem, STRESS_KEY, stress);
+ return (Number.isInteger(tempStress) && tempStress >= 1) ? tempStress : stress;
+ }
+ }
+ }
+ }
+ return stress;
+ }
+
+ getSuiteStress(suiteDesc) {
+ let stress = 1;
+ let suites = ObjectUtils.get(this.data, SUITES_KEY, []);
+ for (const suiteItem of suites) {
+ let describeValue = ObjectUtils.get(suiteItem, DESCRIBE_KEY, []);
+ if (ObjectUtils.has(suiteItem, DESCRIBE_KEY) && (typeof describeValue === 'object') && describeValue.constructor === Array && describeValue.includes(suiteDesc)) {
+ let tempStress = ObjectUtils.get(suiteItem, STRESS_KEY, stress);
+ return (Number.isInteger(tempStress) && tempStress >= 1) ? tempStress : stress;
+ }
+ }
+ return stress;
+ }
+}
+
+export default DataDriver;
diff --git a/oh_modules/@ohos/hypium/src/main/module/config/Filter.js b/oh_modules/@ohos/hypium/src/main/module/config/Filter.js
new file mode 100644
index 0000000000000000000000000000000000000000..0ca3b4f412353ad0e9fa70bcfe775c905b5e02a9
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/config/Filter.js
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class ClassFilter {
+ constructor(suiteName, itName, params) {
+ this.suiteName = suiteName;
+ this.itName = itName;
+ this.params = params;
+ }
+
+ filterSuite() {
+ return !this.params.split(',').map(item => item.split('#')[0]).map(item => item == this.suiteName).reduce((pre, cur) => pre || cur, false);
+ }
+
+ filterIt() {
+ let classArray = this.params.split(',') || [];
+ let suiteFilterResult = classArray.filter(item => !item.includes('#')).map(item => item == this.suiteName).reduce((pre, cur) => pre || cur, false);
+ let itFilterResult = classArray.filter(item => item.includes('#')).map(item => item == (this.suiteName + '#' + this.itName)).reduce((pre, cur) => pre || cur, false);
+ return !(suiteFilterResult || itFilterResult);
+ }
+}
+
+class NotClassFilter {
+ constructor(suiteName, itName, params) {
+ this.suiteName = suiteName;
+ this.itName = itName;
+ this.params = params;
+ }
+
+ filterSuite() {
+ return this.params.split(',').map(item => item == this.suiteName).reduce((pre, cur) => pre || cur, false);
+ }
+
+ filterIt() {
+ return this.params.split(',').some(item => item == (this.suiteName + '#' + this.itName));
+ }
+}
+
+class SuiteAndItNameFilter {
+ constructor(suiteName, itName, params) {
+ this.suiteName = suiteName;
+ this.itName = itName;
+ this.params = params;
+ }
+
+ filterSuite() {
+ return !this.params.split(',').map(item => item == this.suiteName).reduce((pre, cur) => pre || cur, false);
+ }
+
+ filterIt() {
+ return !this.params.split(',').map(item => item == this.itName).reduce((pre, cur) => pre || cur, false);
+ }
+}
+
+
+class TestTypesFilter {
+ constructor(suiteName, itName, fi, params) {
+ this.suiteName = suiteName;
+ this.itName = itName;
+ this.params = params;
+ this.fi = fi;
+ }
+
+ filterIt() {
+ return !((this.params === (this.fi & this.params)) || this.fi === 0);
+ }
+}
+
+export {ClassFilter, NotClassFilter, SuiteAndItNameFilter, TestTypesFilter};
diff --git a/oh_modules/@ohos/hypium/src/main/module/config/configService.js b/oh_modules/@ohos/hypium/src/main/module/config/configService.js
new file mode 100644
index 0000000000000000000000000000000000000000..94f4a764b04d1d190e495a53ed09834f2e411bf2
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/config/configService.js
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {ClassFilter, NotClassFilter, SuiteAndItNameFilter, TestTypesFilter} from './Filter';
+import {TAG} from '../../Constant';
+const STRESS_RULE = /^[1-9]\d*$/;
+
+class ConfigService {
+ constructor(attr) {
+ this.id = attr.id;
+ this.supportAsync = false;
+ this.random = false;
+ this.filterValid = [];
+ this.filter = 0;
+ this.flag = false;
+ this.suite = null;
+ this.itName = null;
+ this.testType = null;
+ this.level = null;
+ this.size = null;
+ this.class = null;
+ this.notClass = null;
+ this.timeout = null;
+ // 遇错即停模式配置
+ this.breakOnError = false;
+ // 压力测试配置
+ this.stress = null;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ }
+
+ isNormalInteger(str) {
+ const n = Math.floor(Number(str));
+ return n !== Infinity && String(n) === String(str) && n >= 0;
+ }
+
+ getStress() {
+ if (this.stress === undefined || this.stress === '' || this.stress === null) {
+ return 1;
+ }
+ return !this.stress.match(STRESS_RULE) ? 1 : Number.parseInt(this.stress);
+ }
+
+ basicParamValidCheck(params) {
+ let size = params.size;
+ if (size !== undefined && size !== '' && size !== null) {
+ let sizeArray = ['small', 'medium', 'large'];
+ if (sizeArray.indexOf(size) === -1) {
+ this.filterValid.push('size:' + size);
+ }
+ }
+ let level = params.level;
+ if (level !== undefined && level !== '' && level !== null) {
+ let levelArray = ['0', '1', '2', '3', '4'];
+ if (levelArray.indexOf(level) === -1) {
+ this.filterValid.push('level:' + level);
+ }
+ }
+ let testType = params.testType;
+ if (testType !== undefined && testType !== '' && testType !== null) {
+ let testTypeArray = ['function', 'performance', 'power', 'reliability', 'security',
+ 'global', 'compatibility', 'user', 'standard', 'safety', 'resilience'];
+ if (testTypeArray.indexOf(testType) === -1) {
+ this.filterValid.push('testType:' + testType);
+ }
+ }
+ }
+
+ filterParamValidCheck(params) {
+ let timeout = params.timeout;
+ if (timeout !== undefined && timeout !== '' && timeout !== null) {
+ if (!this.isNormalInteger(timeout)) {
+ this.filterValid.push('timeout:' + timeout);
+ }
+ }
+
+ let paramKeys = ['dryRun', 'random', 'breakOnError', 'coverage'];
+ for (const key of paramKeys) {
+ if (params[key] !== undefined && params[key] !== 'true' && params[key] !== 'false') {
+ this.filterValid.push(`${key}:${params[key]}`);
+ }
+ }
+
+ // 压力测试参数验证,正整数
+ if (params.stress !== undefined && params.stress !== '' && params.stress !== null) {
+ if (!params.stress.match(STRESS_RULE)) {
+ this.filterValid.push('stress:' + params.stress);
+ }
+ }
+
+ let nameRule = /^[A-Za-z]{1}[\w#,.]*$/;
+ let paramClassKeys = ['class', 'notClass'];
+ for (const key of paramClassKeys) {
+ if (params[key] !== undefined && params[key] !== '' && params[key] !== null) {
+ let classArray = params[key].split(',');
+ classArray.forEach(item => !item.match(nameRule) ? this.filterValid.push(`${key}:${params[key]}`) : null);
+ }
+ }
+ }
+
+ setConfig(params) {
+ this.basicParamValidCheck(params);
+ this.filterParamValidCheck(params);
+ try {
+ this.class = params.class;
+ this.notClass = params.notClass;
+ this.flag = params.flag || {flag: false};
+ this.suite = params.suite;
+ this.itName = params.itName;
+ this.filter = params.filter;
+ this.testType = params.testType;
+ this.level = params.level;
+ this.size = params.size;
+ this.timeout = params.timeout;
+ this.dryRun = params.dryRun;
+ this.breakOnError = params.breakOnError;
+ this.random = params.random === 'true' ? true : false;
+ this.stress = params.stress;
+ this.coverage = params.coverage;
+ this.filterParam = {
+ testType: {
+ 'function': 1,
+ 'performance': 1 << 1,
+ 'power': 1 << 2,
+ 'reliability': 1 << 3,
+ 'security': 1 << 4,
+ 'global': 1 << 5,
+ 'compatibility': 1 << 6,
+ 'user': 1 << 7,
+ 'standard': 1 << 8,
+ 'safety': 1 << 9,
+ 'resilience': 1 << 10,
+ },
+ level: {
+ '0': 1 << 24,
+ '1': 1 << 25,
+ '2': 1 << 26,
+ '3': 1 << 27,
+ '4': 1 << 28,
+ },
+ size: {
+ 'small': 1 << 16,
+ 'medium': 1 << 17,
+ 'large': 1 << 18,
+ }
+ };
+ this.parseParams();
+ } catch (err) {
+ console.info(`${TAG}setConfig error: ${err.message}`);
+ }
+ }
+
+ parseParams() {
+ if (this.filter != null) {
+ return;
+ }
+ let testTypeFilter = 0;
+ let sizeFilter = 0;
+ let levelFilter = 0;
+ if (this.testType != null) {
+ testTypeFilter = this.testType.split(',')
+ .map(item => this.filterParam.testType[item] || 0)
+ .reduce((pre, cur) => pre | cur, 0);
+ }
+ if (this.level != null) {
+ levelFilter = this.level.split(',')
+ .map(item => this.filterParam.level[item] || 0)
+ .reduce((pre, cur) => pre | cur, 0);
+ }
+ if (this.size != null) {
+ sizeFilter = this.size.split(',')
+ .map(item => this.filterParam.size[item] || 0)
+ .reduce((pre, cur) => pre | cur, 0);
+ }
+ this.filter = testTypeFilter | sizeFilter | levelFilter;
+ console.info(`${TAG}filter params:${this.filter}`);
+ }
+
+ isCurrentSuite(description) {
+ if (this.suite !== undefined && this.suite !== '' && this.suite !== null) {
+ let suiteArray = this.suite.split(',');
+ return suiteArray.indexOf(description) !== -1;
+ }
+ return false;
+ }
+
+ filterSuite(currentSuiteName) {
+ let filterArray = [];
+ if (this.suite !== undefined && this.suite !== '' && this.suite !== null) {
+ filterArray.push(new SuiteAndItNameFilter(currentSuiteName, '', this.suite));
+ }
+ if (this.class !== undefined && this.class !== '' && this.class !== null) {
+ filterArray.push(new ClassFilter(currentSuiteName, '', this.class));
+ }
+ if (this.notClass !== undefined && this.notClass !== '' && this.notClass !== null) {
+ filterArray.push(new NotClassFilter(currentSuiteName, '', this.notClass));
+ }
+
+ let result = filterArray.map(item => item.filterSuite()).reduce((pre, cur) => pre || cur, false);
+ return result;
+ }
+
+ filterDesc(currentSuiteName, desc, fi, coreContext) {
+ let filterArray = [];
+ if (this.itName !== undefined && this.itName !== '' && this.itName !== null) {
+ filterArray.push(new SuiteAndItNameFilter(currentSuiteName, desc, this.itName));
+ }
+ if (this.class !== undefined && this.class !== '' && this.class !== null) {
+ filterArray.push(new ClassFilter(currentSuiteName, desc, this.class));
+ }
+ if (this.notClass !== undefined && this.notClass !== '' && this.notClass !== null) {
+ filterArray.push(new NotClassFilter(currentSuiteName, desc, this.notClass));
+ }
+ if (typeof (this.filter) !== 'undefined' && this.filter !== 0 && fi !== 0) {
+ filterArray.push(new TestTypesFilter('', '', fi, this.filter));
+ }
+ let result = filterArray.map(item => item.filterIt()).reduce((pre, cur) => pre || cur, false);
+ return result;
+ }
+
+ isRandom() {
+ return this.random || false;
+ }
+
+ isBreakOnError() {
+ return this.breakOnError !== true ? false : true;
+ }
+
+ setSupportAsync(value) {
+ this.supportAsync = value;
+ }
+
+ isSupportAsync() {
+ return this.supportAsync;
+ }
+
+ translateParams(parameters) {
+ const keySet = new Set([
+ '-s class', '-s notClass', '-s suite', '-s itName',
+ '-s level', '-s testType', '-s size', '-s timeout',
+ '-s dryRun', '-s random', '-s breakOnError', '-s stress',
+ '-s coverage', 'class', 'notClass', 'suite', 'itName',
+ 'level', 'testType', 'size', 'timeout', 'dryRun', 'random',
+ 'breakOnError', 'stress', 'coverage'
+ ]);
+ let targetParams = {};
+ for (const key in parameters) {
+ if (keySet.has(key)) {
+ var newKey = key.replace("-s ", "");
+ targetParams[newKey] = parameters[key];
+ }
+ }
+ return targetParams;
+ }
+ translateParamsToString(parameters) {
+ const keySet = new Set([
+ '-s class', '-s notClass', '-s suite', '-s itName',
+ '-s level', '-s testType', '-s size', '-s timeout',
+ '-s dryRun', '-s random', '-s breakOnError', '-s stress',
+ '-s coverage', 'class', 'notClass', 'suite', 'itName',
+ 'level', 'testType', 'size', 'timeout', 'dryRun', 'random',
+ 'breakOnError', 'stress', 'coverage'
+ ]);
+ let targetParams = '';
+ for (const key in parameters) {
+ if (keySet.has(key)) {
+ targetParams += ' ' + key + ' ' + parameters[key];
+ }
+ }
+ return targetParams.trim();
+ }
+
+ execute() {
+ }
+}
+
+export {
+ ConfigService
+};
diff --git a/oh_modules/@ohos/hypium/src/main/module/coverage/coverageCollect.js b/oh_modules/@ohos/hypium/src/main/module/coverage/coverageCollect.js
new file mode 100644
index 0000000000000000000000000000000000000000..632a6820503dcdec7646add5ee6a2c6b3c6227bb
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/coverage/coverageCollect.js
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import SysTestKit from "../kit/SysTestKit";
+
+export async function collectCoverageData() {
+ if (globalThis.__coverage__ === undefined) {
+ return;
+ }
+ const strJson = JSON.stringify(globalThis.__coverage__);
+ const strLen = strJson.length;
+ const maxLen = 500;
+ const maxCount = Math.floor(strLen / maxLen);
+ const OHOS_REPORT_COVERAGE_DATA = 'OHOS_REPORT_COVERAGE_DATA:';
+ for (let count = 0; count <= maxCount; count++) {
+ console.info(`${OHOS_REPORT_COVERAGE_DATA} ${strJson.substring(count * maxLen, (count + 1) * maxLen)}`);
+ await SysTestKit.print(`${OHOS_REPORT_COVERAGE_DATA} ${strJson.substring(count * maxLen, (count + 1) * maxLen)}`);
+ }
+}
\ No newline at end of file
diff --git a/oh_modules/@ohos/hypium/src/main/module/kit/SysTestKit.js b/oh_modules/@ohos/hypium/src/main/module/kit/SysTestKit.js
new file mode 100644
index 0000000000000000000000000000000000000000..65d063c7d56a85f64967103922a6b261bd79c0b8
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/kit/SysTestKit.js
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {TAG} from '../../Constant';
+
+export default class SysTestKit {
+
+ static delegator = null;
+ static systemTime = null;
+
+ constructor() {
+ this.id = 'sysTestKit';
+ this.index = 0;
+ }
+
+ static actionStart(tag) {
+ console.info(`${TAG}${JSON.stringify(tag)}`);
+ var message = '\n' + 'OHOS_REPORT_ACTIONSTART: ' + JSON.stringify(tag) + '\n';
+ SysTestKit.print(message);
+ console.info(`${TAG}${JSON.stringify(tag)} actionStart print success`);
+ }
+
+ static actionEnd(tag) {
+ console.info(`${TAG}${JSON.stringify(tag)}`);
+ var message = '\n' + 'OHOS_REPORT_ACTIONEND: ' + JSON.stringify(tag) + '\n';
+ SysTestKit.print(message);
+ console.info(`${TAG}${JSON.stringify(tag)} actionEnd print success`);
+ }
+
+ static async existKeyword(keyword, timeout) {
+ let reg = new RegExp(/^[a-zA-Z0-9]{1,}$/);
+ if (!reg.test(keyword)) {
+ throw new Error('keyword must contain more than one string, and only letters and numbers are supported.');
+ }
+ timeout = timeout || 4;
+
+ let searchResult = false;
+ let cmd = 'hilog -x | grep -i \'' + keyword + '\' | wc -l';
+ await executePromise(cmd, timeout).then((data) => {
+ searchResult = data;
+ });
+ return searchResult;
+ }
+ static async print(message) {
+ if ('printSync' in SysTestKit.delegator) {
+ console.debug(`${TAG}printSync called ...`);
+ SysTestKit.delegator.printSync(message);
+ } else {
+ await SysTestKit.delegator.print(message);
+ }
+ }
+
+ static async getRealTime() {
+ let currentTime = new Date().getTime();
+ if (SysTestKit.systemTime !== null && SysTestKit.systemTime !== undefined) {
+ await SysTestKit.systemTime.getRealTime().then((time) => {
+ console.info(`${TAG}systemTime.getRealTime success data: ${JSON.stringify(time)}`);
+ currentTime = time;
+ }).catch((error) => {
+ console.error(`${TAG}failed to systemTime.getRealTime because ${JSON.stringify(error)}`);
+ });
+ }
+ return currentTime;
+ }
+}
+
+function executePromise(cmd, timeout) {
+ return new Promise((resolve, reject) => {
+ SysTestKit.delegator.executeShellCommand(cmd, timeout,
+ (error, data) => {
+ console.info(`${TAG}existKeyword CallBack: err : ${JSON.stringify(error)}`);
+ console.info(`${TAG}existKeyword CallBack: data : ${JSON.stringify(data)}`);
+ resolve(parseInt(data.stdResult) > 3 ? true : false);
+ });
+ });
+}
\ No newline at end of file
diff --git a/oh_modules/@ohos/hypium/src/main/module/mock/ArgumentMatchers.js b/oh_modules/@ohos/hypium/src/main/module/mock/ArgumentMatchers.js
new file mode 100644
index 0000000000000000000000000000000000000000..6a9d7aac464e95383ea31385284b6603c34e084c
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/mock/ArgumentMatchers.js
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class ArgumentMatchers {
+ ANY = "";
+ ANY_STRING = "";
+ ANY_BOOLEAN = "";
+ ANY_NUMBER = "";
+ ANY_OBJECT = "";
+ ANY_FUNCTION = "";
+ MATCH_REGEXS = "";
+
+ static any() {
+ }
+
+ static anyString() {
+ }
+
+ static anyBoolean() {
+ }
+
+ static anyNumber() {
+ }
+
+ static anyObj() {
+ }
+
+ static anyFunction() {
+ }
+
+ static matchRegexs() {
+ let regex = arguments[0];
+ if (ArgumentMatchers.isRegExp(regex)) {
+ return regex;
+ }
+ throw Error("not a regex");
+ }
+
+ static isRegExp(value) {
+ return Object.prototype.toString.call(value) === "[object RegExp]";
+ }
+
+ matcheReturnKey() {
+ let arg = arguments[0];
+ let regex = arguments[1];
+ let stubSetKey = arguments[2];
+
+ if (stubSetKey && stubSetKey == this.ANY) {
+ return this.ANY;
+ }
+
+ if (typeof arg === "string" && !regex) {
+ return this.ANY_STRING;
+ }
+
+ if (typeof arg === "boolean" && !regex) {
+ return this.ANY_BOOLEAN;
+ }
+
+ if (typeof arg === "number" && !regex) {
+ return this.ANY_NUMBER;
+ }
+
+ if (typeof arg === "object" && !regex) {
+ return this.ANY_OBJECT;
+ }
+
+ if (typeof arg === "function" && !regex) {
+ return this.ANY_FUNCTION;
+ }
+
+ if (typeof arg === "string" && regex) {
+ return regex.test(arg);
+ }
+
+ return null;
+ }
+
+ matcheStubKey() {
+ let key = arguments[0];
+
+ if (key === ArgumentMatchers.any) {
+ return this.ANY;
+ }
+
+ if (key === ArgumentMatchers.anyString) {
+ return this.ANY_STRING;
+ }
+ if (key === ArgumentMatchers.anyBoolean) {
+ return this.ANY_BOOLEAN;
+ }
+ if (key === ArgumentMatchers.anyNumber) {
+ return this.ANY_NUMBER;
+ }
+ if (key === ArgumentMatchers.anyObj) {
+ return this.ANY_OBJECT;
+ }
+ if (key === ArgumentMatchers.anyFunction) {
+ return this.ANY_FUNCTION;
+ }
+
+ if (ArgumentMatchers.isRegExp(key)) {
+ return key;
+ }
+
+ return null;
+ }
+}
+
+export default ArgumentMatchers;
\ No newline at end of file
diff --git a/oh_modules/@ohos/hypium/src/main/module/mock/ExtendInterface.js b/oh_modules/@ohos/hypium/src/main/module/mock/ExtendInterface.js
new file mode 100644
index 0000000000000000000000000000000000000000..c6a866a6df662ad10a7f6869dcbc2381fa47bcdc
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/mock/ExtendInterface.js
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class ExtendInterface {
+ constructor(mocker) {
+ this.mocker = mocker;
+ }
+
+ stub() {
+ this.params = arguments;
+ return this;
+ }
+
+ stubMockedCall(returnInfo) {
+ this.mocker.stubApply(this, this.params, returnInfo);
+ }
+
+ afterReturn(value) {
+ this.stubMockedCall(function () {
+ return value;
+ });
+ }
+
+ afterReturnNothing() {
+ this.stubMockedCall(function () {
+ return undefined;
+ });
+ }
+
+ afterAction(action) {
+ this.stubMockedCall(action);
+ }
+
+ afterThrow(msg) {
+ this.stubMockedCall(function () {
+ throw msg;
+ });
+ }
+
+ clear() {
+ this.mocker.clear();
+ }
+}
+
+export default ExtendInterface;
\ No newline at end of file
diff --git a/oh_modules/@ohos/hypium/src/main/module/mock/MockKit.js b/oh_modules/@ohos/hypium/src/main/module/mock/MockKit.js
new file mode 100644
index 0000000000000000000000000000000000000000..1bd83be8a3eb8435486013fe1be5947e0fbe574e
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/mock/MockKit.js
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import ExtendInterface from "./ExtendInterface";
+import VerificationMode from "./VerificationMode";
+import ArgumentMatchers from "./ArgumentMatchers";
+
+class MockKit {
+
+ constructor() {
+ this.mFunctions = [];
+ this.stubs = new Map();
+ this.recordCalls = new Map();
+ this.currentSetKey = new Map();
+ this.mockObj = null;
+ this.recordMockedMethod = new Map();
+ }
+
+ init() {
+ this.reset();
+ }
+
+ reset() {
+ this.mFunctions = [];
+ this.stubs = {};
+ this.recordCalls = {};
+ this.currentSetKey = new Map();
+ this.mockObj = null;
+ this.recordMockedMethod = new Map();
+ }
+
+ clearAll() {
+ this.reset();
+ var props = Object.keys(this);
+ for (var i = 0; i < props.length; i++) {
+ delete this[props[i]];
+ }
+
+ var props = Object.getOwnPropertyNames(this);
+ for (var i = 0; i < props.length; i++) {
+ delete this[props[i]];
+ }
+ for (var key in this) {
+ delete this[key];
+ }
+ }
+
+ clear(obj) {
+ if (!obj) throw Error("Please enter an object to be cleaned");
+ if (typeof (obj) != 'object') throw new Error('Not a object');
+ this.recordMockedMethod.forEach(function (value, key, map) {
+ if (key) {
+ obj[key] = value;
+ }
+ });
+ }
+
+ ignoreMock(obj, method) {
+ if (typeof (obj) != 'object') throw new Error('Not a object');
+ if (typeof (method) != 'function') throw new Error('Not a function');
+ let og = this.recordMockedMethod.get(method.propName);
+ if (og) {
+ obj[method.propName] = og;
+ this.recordMockedMethod.set(method.propName, undefined);
+ }
+ }
+
+ extend(dest, source) {
+ dest["stub"] = source["stub"];
+ dest["afterReturn"] = source["afterReturn"];
+ dest["afterReturnNothing"] = source["afterReturnNothing"];
+ dest["afterAction"] = source["afterAction"];
+ dest["afterThrow"] = source["afterThrow"];
+ dest["stubMockedCall"] = source["stubMockedCall"];
+ dest["clear"] = source["clear"];
+ return dest;
+ }
+
+ stubApply(f, params, returnInfo) {
+ let values = this.stubs.get(f);
+ if (!values) {
+ values = new Map();
+ }
+ let key = params[0];
+ if (typeof key == "undefined") {
+ key = "anonymous-mock-" + f.propName;
+ }
+ let matcher = new ArgumentMatchers();
+ if (matcher.matcheStubKey(key)) {
+ key = matcher.matcheStubKey(key);
+ if (key) {
+ this.currentSetKey.set(f, key);
+ }
+ }
+ values.set(key, returnInfo);
+ this.stubs.set(f, values);
+ }
+
+ getReturnInfo(f, params) {
+ let values = this.stubs.get(f);
+ if (!values) {
+ return undefined;
+ }
+ let retrunKet = params[0];
+ if (typeof retrunKet == "undefined") {
+ retrunKet = "anonymous-mock-" + f.propName;
+ }
+ let stubSetKey = this.currentSetKey.get(f);
+
+ if (stubSetKey && (typeof (retrunKet) != "undefined")) {
+ retrunKet = stubSetKey;
+ }
+ let matcher = new ArgumentMatchers();
+ if (matcher.matcheReturnKey(params[0], undefined, stubSetKey) && matcher.matcheReturnKey(params[0], undefined, stubSetKey) != stubSetKey) {
+ retrunKet = params[0];
+ }
+
+ values.forEach(function (value, key, map) {
+ if (ArgumentMatchers.isRegExp(key) && matcher.matcheReturnKey(params[0], key)) {
+ retrunKet = key;
+ }
+ });
+
+ return values.get(retrunKet);
+ }
+
+ findName(obj, value) {
+ let properties = this.findProperties(obj);
+ let name = null;
+ properties.filter(item => (item !== 'caller' && item !== 'arguments')).forEach(
+ function (va1, idx, array) {
+ if (obj[va1] === value) {
+ name = va1;
+ }
+ }
+ );
+ return name;
+ }
+
+ isFunctionFromPrototype(f, container, propName) {
+ if (container.constructor != Object && container.constructor.prototype !== container) {
+ return container.constructor.prototype[propName] === f;
+ }
+ return false;
+ }
+
+ findProperties(obj, ...arg) {
+ function getProperty(new_obj) {
+ if (new_obj.__proto__ === null) {
+ return [];
+ }
+ let properties = Object.getOwnPropertyNames(new_obj);
+ return [...properties, ...getProperty(new_obj.__proto__)];
+ }
+ return getProperty(obj);
+ }
+
+ recordMethodCall(originalMethod, args) {
+ Function.prototype.getName = function () {
+ return this.name || this.toString().match(/function\s*([^(]*)\(/)[1];
+ };
+ let name = originalMethod.getName();
+ let arglistString = name + '(' + Array.from(args).toString() + ')';
+ let records = this.recordCalls.get(arglistString);
+ if (!records) {
+ records = 0;
+ }
+ records++;
+ this.recordCalls.set(arglistString, records);
+ }
+
+ mockFunc(originalObject, originalMethod) {
+ let tmp = this;
+ this.originalMethod = originalMethod;
+ let f = function () {
+ let args = arguments;
+ let action = tmp.getReturnInfo(f, args);
+ if (originalMethod) {
+ tmp.recordMethodCall(originalMethod, args);
+ }
+ if (action) {
+ return action.apply(this, args);
+ }
+ };
+
+ f.container = null || originalObject;
+ f.original = originalMethod || null;
+
+ if (originalObject && originalMethod) {
+ if (typeof (originalMethod) != 'function') throw new Error('Not a function');
+ var name = this.findName(originalObject, originalMethod);
+ originalObject[name] = f;
+ this.recordMockedMethod.set(name, originalMethod);
+ f.propName = name;
+ f.originalFromPrototype = this.isFunctionFromPrototype(f.original, originalObject, f.propName);
+ }
+ f.mocker = this;
+ this.mFunctions.push(f);
+ this.extend(f, new ExtendInterface(this));
+ return f;
+ }
+
+ verify(methodName, argsArray) {
+ if (!methodName) {
+ throw Error("not a function name");
+ }
+ let a = this.recordCalls.get(methodName + '(' + argsArray.toString() + ')');
+ return new VerificationMode(a ? a : 0);
+ }
+
+ mockObject(object) {
+ if (!object || typeof object === "string") {
+ throw Error(`this ${object} cannot be mocked`);
+ }
+ const _this = this;
+ let mockedObject = {};
+ let keys = Reflect.ownKeys(object);
+ keys.filter(key => (typeof Reflect.get(object, key)) === 'function')
+ .forEach(key => {
+ mockedObject[key] = object[key];
+ mockedObject[key] = _this.mockFunc(mockedObject, mockedObject[key]);
+ });
+ return mockedObject;
+ }
+}
+
+function ifMockedFunction(f) {
+ if (Object.prototype.toString.call(f) != "[object Function]" &&
+ Object.prototype.toString.call(f) != "[object AsyncFunction]") {
+ throw Error("not a function");
+ }
+ if (!f.stub) {
+ throw Error("not a mock function");
+ }
+ return true;
+}
+
+function when(f) {
+ if (ifMockedFunction(f)) {
+ return f.stub.bind(f);
+ }
+}
+
+export {MockKit, when};
\ No newline at end of file
diff --git a/oh_modules/@ohos/hypium/src/main/module/mock/VerificationMode.js b/oh_modules/@ohos/hypium/src/main/module/mock/VerificationMode.js
new file mode 100644
index 0000000000000000000000000000000000000000..28eda2b05fa5ec9f78f9b20d1be1b6c87ffaf33b
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/mock/VerificationMode.js
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {expect} from '../../interface';
+
+class VerificationMode {
+ constructor(times) {
+ this.doTimes = times;
+ }
+
+ times(count) {
+ expect(count).assertEqual(this.doTimes);
+ }
+
+ never() {
+ console.log(this.doTimes);
+ expect(0).assertEqual(this.doTimes);
+ }
+
+ once() {
+ expect(1).assertEqual(this.doTimes);
+ }
+
+ atLeast(count) {
+ if (count > this.doTimes) {
+ throw Error('failed ' + count + ' greater than the actual execution times of method');
+ }
+ }
+
+ atMost(count) {
+ if (count < this.doTimes) {
+ throw Error('failed ' + count + ' less than the actual execution times of method');
+ }
+ }
+}
+
+export default VerificationMode;
\ No newline at end of file
diff --git a/oh_modules/@ohos/hypium/src/main/module/report/OhReport.js b/oh_modules/@ohos/hypium/src/main/module/report/OhReport.js
new file mode 100644
index 0000000000000000000000000000000000000000..f648b11a9d0fd487cc0cc83b1ed360a788c5d700
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/report/OhReport.js
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import SysTestKit from "../kit/SysTestKit";
+import {collectCoverageData} from '../coverage/coverageCollect';
+import {TAG} from '../../Constant';
+
+class OhReport {
+ constructor(attr) {
+ this.delegator = attr.delegator;
+ this.abilityDelegatorArguments = attr.abilityDelegatorArguments;
+ this.id = 'report';
+ this.index = 0;
+ this.duration = 0;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ this.suiteService = this.coreContext.getDefaultService('suite');
+ this.specService = this.coreContext.getDefaultService('spec');
+ }
+
+ taskStart() {
+ }
+
+ async taskDone() {
+ if (this.abilityDelegatorArguments !== null) {
+ this.taskDoneTime = new Date().getTime();
+ let summary = this.suiteService.getSummary();
+ const configService = this.coreContext.getDefaultService('config');
+ if (configService['coverage'] === 'true') {
+ await collectCoverageData();
+ }
+ let message = '\n' + 'OHOS_REPORT_RESULT: stream=Tests run: ' + summary.total + ', Failure: ' + summary.failure;
+ message += ', Error: ' + summary.error;
+ message += ', Pass: ' + summary.pass;
+ message += ', Ignore: ' + summary.ignore;
+ message += '\n' + 'OHOS_REPORT_CODE: ' + (summary.failure > 0 ? -1 : 0) + '\n';
+ let isHasError = summary.failure > 0 || summary.error > 0;
+ let config = this.coreContext.getDefaultService('config');
+ if (config.isBreakOnError() && isHasError) {
+ // 未执行全部说明
+ message += '\n' + 'OHOS_REPORT_RESULT: breakOnError model, Stopping whole test suite if one specific test case failed or error' + '\n';
+ }
+ message += 'OHOS_REPORT_STATUS: taskconsuming=' + summary.duration + '\n';
+ console.info(`${message}`);
+ await SysTestKit.print(message);
+ }
+ console.info(`${TAG}report print success`);
+ this.delegator.finishTest('your test finished!!!', 0, () => { });
+ }
+
+ incorrectFormat() {
+ if (this.coreContext.getDefaultService('config').filterValid.length !== 0) {
+ var value = this.coreContext.getDefaultService('config').filterValid;
+ var message = 'this param ' + value.join(',') + ' is invalid' + '\n';
+ this.delegator.finishTest(message, 0, () => {
+ });
+ }
+ }
+
+ async suiteStart() {
+ if (this.abilityDelegatorArguments !== null) {
+ let message = '\n' + 'OHOS_REPORT_SUM: ' + this.suiteService.getCurrentRunningSuite().getSpecsNum();
+ message += '\n' + 'OHOS_REPORT_STATUS: class=' + this.suiteService.getCurrentRunningSuite().description + '\n';
+ console.info(`${message}`);
+ await SysTestKit.print(message);
+ console.info(`${TAG}${this.suiteService.getCurrentRunningSuite().description} suiteStart print success`);
+ }
+ }
+
+ async suiteDone() {
+ if (this.abilityDelegatorArguments !== null) {
+ const currentRunningSuite = this.suiteService.getCurrentRunningSuite();
+ let message = '\n' + 'OHOS_REPORT_STATUS: class=' + this.suiteService.getCurrentRunningSuite().description;
+ message += '\n' + 'OHOS_REPORT_STATUS: suiteconsuming=' + this.suiteService.getCurrentRunningSuite().duration;
+ if (currentRunningSuite.hookError) {
+ message += '\n' + `OHOS_REPORT_STATUS: ${currentRunningSuite.hookError.message}`;
+ }
+ message += '\n';
+ console.info(`${message}`);
+ await SysTestKit.print(message);
+ console.info(`${TAG}${this.suiteService.getCurrentRunningSuite().description} suiteDone print success`);
+ }
+ }
+
+ async specStart() {
+ if (this.abilityDelegatorArguments !== null) {
+ let message = '\n' + 'OHOS_REPORT_STATUS: class=' + this.suiteService.getCurrentRunningSuite().description;
+ message += '\n' + 'OHOS_REPORT_STATUS: current=' + (++this.index);
+ message += '\n' + 'OHOS_REPORT_STATUS: id=JS';
+ message += '\n' + 'OHOS_REPORT_STATUS: numtests=' + this.specService.getTestTotal();
+ message += '\n' + 'OHOS_REPORT_STATUS: stream=';
+ message += '\n' + 'OHOS_REPORT_STATUS: test=' + this.specService.currentRunningSpec.description;
+ message += '\n' + 'OHOS_REPORT_STATUS_CODE: 1' + '\n';
+ console.info(`${message}`);
+ await SysTestKit.print(message);
+ console.info(`${TAG}${this.specService.currentRunningSpec.description} specStart start print success`);
+ }
+ }
+
+ async specDone() {
+ if (this.abilityDelegatorArguments !== null) {
+ let message = '\n' + 'OHOS_REPORT_STATUS: class=' + this.suiteService.getCurrentRunningSuite().description;
+ message += '\n' + 'OHOS_REPORT_STATUS: current=' + (this.index);
+ message += '\n' + 'OHOS_REPORT_STATUS: id=JS';
+ message += '\n' + 'OHOS_REPORT_STATUS: numtests=' + this.specService.getTestTotal();
+ let errorMsg = '';
+ if (this.specService.currentRunningSpec.error) {
+ message += '\n' + 'OHOS_REPORT_STATUS: stack=' + this.specService.currentRunningSpec.error.message;
+ message += '\n' + 'OHOS_REPORT_STATUS: stream=';
+ message += '\n' + 'Error in ' + this.specService.currentRunningSpec.description;
+ message += '\n' + this.specService.currentRunningSpec.error.message;
+ message += '\n' + 'OHOS_REPORT_STATUS: test=' + this.specService.currentRunningSpec.description;
+ message += '\n' + 'OHOS_REPORT_STATUS_CODE: -1' + '\n';
+ } else if (this.specService.currentRunningSpec) {
+ if (this.specService.currentRunningSpec.fail) {
+ errorMsg = this.specService.currentRunningSpec.fail?.message;
+ message += '\n' + 'OHOS_REPORT_STATUS: stack=' + errorMsg;
+ message += '\n' + 'OHOS_REPORT_STATUS: stream=';
+ message += '\n' + 'Error in ' + this.specService.currentRunningSpec.description;
+ message += '\n' + errorMsg + '\n' + 'OHOS_REPORT_STATUS: test=' + this.specService.currentRunningSpec.description;
+ message += '\n' + 'OHOS_REPORT_STATUS_CODE: -2' + '\n';
+ } else {
+ message += '\n' + 'OHOS_REPORT_STATUS: stream=';
+ message += '\n' + 'OHOS_REPORT_STATUS: test=' + this.specService.currentRunningSpec.description;
+ message += '\n' + 'OHOS_REPORT_STATUS_CODE: 0' + '\n';
+ }
+ } else {
+ message += '\n';
+ }
+ message += 'OHOS_REPORT_STATUS: consuming=' + this.specService.currentRunningSpec.duration + '\n';
+ console.info(`${message}`);
+ await SysTestKit.print(message);
+ console.info(`${TAG}${this.specService.currentRunningSpec.description} specDone end print success`);
+ }
+ }
+}
+
+export default OhReport;
diff --git a/oh_modules/@ohos/hypium/src/main/module/report/ReportExtend.js b/oh_modules/@ohos/hypium/src/main/module/report/ReportExtend.js
new file mode 100644
index 0000000000000000000000000000000000000000..852fbcd5cbf97e776ebe5177a029df0f516594a5
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/module/report/ReportExtend.js
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class ReportExtend {
+ constructor(fileModule) {
+ this.id = 'extend';
+ this.fileModule = fileModule;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ this.suiteService = this.coreContext.getDefaultService('suite');
+ }
+
+ taskStart() {
+
+ }
+
+ taskDone() {
+ const report = {
+ tag: 'testsuites',
+ name: 'summary_report',
+ timestamp: new Date().toDateString(),
+ time: '1',
+ errors: 0,
+ failures: 0,
+ tests: 0,
+ children: []
+ };
+ const rootSuite = this.suiteService.rootSuite;
+ if (rootSuite && rootSuite.childSuites) {
+ for (let testsuite of rootSuite.childSuites) {
+ let suiteReport = {
+ tag: 'testsuite',
+ name: testsuite['description'],
+ errors: 0,
+ tests: 0,
+ failures: 0,
+ time: '0.1',
+ children: []
+ };
+ let specs = testsuite['specs'];
+ for (let testcase of specs) {
+ report.tests++;
+ suiteReport.tests++;
+ let caseReport = {
+ tag: 'testcase',
+ name: testcase['description'],
+ status: 'run',
+ time: '0.0',
+ classname: testsuite['description']
+ };
+ if (testcase.error) {
+ caseReport['result'] = false;
+ caseReport['children'] = [{
+ tag: 'error',
+ type: '',
+ message: testcase.error.message
+ }];
+ report.errors++;
+ suiteReport.errors++;
+ } else if (testcase.result.failExpects.length > 0) {
+ caseReport['result'] = false;
+ let message = '';
+ testcase.result.failExpects.forEach(failExpect => {
+ message += failExpect.message || ('expect ' + failExpect.actualValue + ' ' + failExpect.checkFunc + ' ' + (failExpect.expectValue || '')) + ';';
+ });
+ caseReport['children'] = [{
+ tag: 'failure',
+ type: '',
+ message: message
+ }];
+ report.failures++;
+ suiteReport.failures++;
+ } else {
+ caseReport['result'] = true;
+ }
+ suiteReport.children.push(caseReport);
+ }
+ report.children.push(suiteReport);
+ }
+ }
+
+ let reportXml = '\n' + json2xml(report);
+ this.fileModule.writeText({
+ uri: 'internal://app/report.xml',
+ text: reportXml,
+ success: function () {
+ console.info('call success callback success');
+ },
+ fail: function (data, code) {
+ console.info('call fail callback success:');
+ },
+ complete: function () {
+ console.info('call complete callback success');
+ }
+ });
+ }
+}
+
+function json2xml(json) {
+ let tagName;
+ let hasChildren = false;
+ let childrenStr = '';
+ let attrStr = '';
+ for (let key in json) {
+ if (key === 'tag') {
+ tagName = json[key];
+ } else if (key === 'children') {
+ if (json[key].length > 0) {
+ hasChildren = true;
+ for (let child of json[key]) {
+ childrenStr += json2xml(child);
+ }
+ }
+ } else {
+ attrStr += ` ${key}="${json[key]}"`;
+ }
+ }
+ let xml = `<${tagName}${attrStr}`;
+ xml += hasChildren ? `>${childrenStr}${tagName}>` : '/>';
+ return xml;
+}
+
+export default ReportExtend;
diff --git a/oh_modules/@ohos/hypium/src/main/service.js b/oh_modules/@ohos/hypium/src/main/service.js
new file mode 100644
index 0000000000000000000000000000000000000000..55d04a8fc206b3ffe52f80e90e07c3fbf56be687
--- /dev/null
+++ b/oh_modules/@ohos/hypium/src/main/service.js
@@ -0,0 +1,966 @@
+/*
+ * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import SysTestKit from "./module/kit/SysTestKit";
+import {TAG} from './Constant';
+
+class AssertException extends Error {
+ constructor(message) {
+ super();
+ this.name = "AssertException";
+ this.message = message;
+ }
+}
+
+function getFuncWithArgsZero(func, timeout, isStressTest) {
+ return new Promise(async (resolve, reject) => {
+ let timer = null;
+ if (!isStressTest) {
+ timer = setTimeout(() => {
+ reject(new Error('execute timeout ' + timeout + 'ms'));
+ }, timeout);
+ }
+ try {
+ await func();
+ } catch (err) {
+ reject(err);
+ }
+ timer !== null ? clearTimeout(timer) : null;
+ resolve();
+ });
+}
+
+function getFuncWithArgsOne(func, timeout, isStressTest) {
+ return new Promise(async (resolve, reject) => {
+ let timer = null;
+ if (!isStressTest) {
+ timer = setTimeout(() => {
+ reject(new Error('execute timeout ' + timeout + 'ms'));
+ }, timeout);;
+ }
+
+ function done() {
+ timer !== null ? clearTimeout(timer) : null;
+ resolve();
+ }
+
+ try {
+ await func(done);
+ } catch (err) {
+ timer !== null ? clearTimeout(timer) : null;
+ reject(err);
+ }
+ });
+}
+
+function getFuncWithArgsTwo(func, timeout, paramItem, isStressTest) {
+ return new Promise(async (resolve, reject) => {
+ let timer = null;
+ if (!isStressTest) {
+ timer = setTimeout(() => {
+ reject(new Error('execute timeout ' + timeout + 'ms'));
+ }, timeout);
+ }
+
+ function done() {
+ timer !== null ? clearTimeout(timer) : null;
+ resolve();
+ }
+
+ try {
+ await func(done, paramItem);
+ } catch (err) {
+ timer !== null ? clearTimeout(timer) : null;
+ reject(err);
+ }
+ });
+}
+
+function processFunc(coreContext, func) {
+ let argNames = ((func || '').toString()
+ .replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg, '')
+ .match(/^(function)?\s*[^\(]*\(\s*([^\)]*)\)/m) || ['', '', ''])[2]
+ .split(',') // split parameters
+ .map(item => item.replace(/^\s*(_?)(.+?)\1\s*$/, name => name.split('=')[0].trim()))
+ .filter(String);
+ let funcLen = func.length;
+ let processedFunc;
+ const config = coreContext.getDefaultService('config');
+ config.setSupportAsync(true);
+ const timeout = + (config.timeout === undefined ? 5000 : config.timeout);
+ const isStressTest = (coreContext.getServices('dataDriver') !== undefined || config.getStress() > 1);
+ switch (funcLen) {
+ case 0: {
+ processedFunc = function () {
+ return getFuncWithArgsZero(func, timeout, isStressTest);
+ };
+ break;
+ }
+ case 1: {
+ if (argNames[0] === 'data') {
+ processedFunc = function (paramItem) {
+ func(paramItem);
+ };
+ } else {
+ processedFunc = function () {
+ return getFuncWithArgsOne(func, timeout, isStressTest);
+ };
+ }
+ break;
+ }
+ default: {
+ processedFunc = function (paramItem) {
+ return getFuncWithArgsTwo(func, timeout, paramItem, isStressTest);
+ };
+ break;
+ }
+ }
+ return processedFunc;
+}
+
+function secureRandomNumber() {
+ return crypto.randomBytes(8).readUInt32LE() / 0xffffffff;
+}
+
+class SuiteService {
+ constructor(attr) {
+ this.id = attr.id;
+ this.rootSuite = new SuiteService.Suite({});
+ this.currentRunningSuite = this.rootSuite;
+ this.suitesStack = [this.rootSuite];
+ }
+
+ describe(desc, func) {
+ const configService = this.coreContext.getDefaultService('config');
+ if (configService.filterSuite(desc)) {
+ console.info(`${TAG}filter suite : ${desc}`);
+ return;
+ }
+ const suite = new SuiteService.Suite({description: desc});
+ if (typeof this.coreContext.getServices('dataDriver') !== 'undefined' && configService['dryRun'] !== 'true') {
+ let suiteStress = this.coreContext.getServices('dataDriver').dataDriver.getSuiteStress(desc);
+ for (let i = 1; i < suiteStress; i++) {
+ this.currentRunningSuite.childSuites.push(suite);
+ }
+ }
+ this.currentRunningSuite.childSuites.push(suite);
+ this.currentRunningSuite = suite;
+ this.suitesStack.push(suite);
+ func.call();
+ let childSuite = this.suitesStack.pop();
+ if (this.suitesStack.length === 0) {
+ this.currentRunningSuite = childSuite;
+ this.suitesStack.push(childSuite);
+ }
+ if (this.suitesStack.length > 1) {
+ this.currentRunningSuite = this.suitesStack.pop();
+ } else {
+ this.currentRunningSuite = this.suitesStack.pop();
+ this.suitesStack.push(this.currentRunningSuite);
+ }
+ }
+
+ beforeAll(func) {
+ this.currentRunningSuite.beforeAll.push(processFunc(this.coreContext, func));
+ }
+
+ beforeEach(func) {
+ this.currentRunningSuite.beforeEach.push(processFunc(this.coreContext, func));
+ }
+
+ afterAll(func) {
+ this.currentRunningSuite.afterAll.push(processFunc(this.coreContext, func));
+ }
+
+ afterEach(func) {
+ this.currentRunningSuite.afterEach.push(processFunc(this.coreContext, func));
+ }
+
+ getCurrentRunningSuite() {
+ return this.currentRunningSuite;
+ }
+
+ setCurrentRunningSuite(suite) {
+ this.currentRunningSuite = suite;
+ }
+
+ traversalResults(suite, obj, breakOnError) {
+ if (suite.childSuites.length === 0 && suite.specs.length === 0) {
+ return obj;
+ }
+ if (suite.specs.length > 0) {
+ for (const itItem of suite.specs) {
+ obj.total++;
+ if (breakOnError && (obj.error > 0 || obj.failure > 0)) { // breakOnError模式
+ continue;
+ }
+ if (itItem.error) {
+ obj.error++;
+ } else if (itItem.fail) {
+ obj.failure++;
+ } else if (itItem.pass === true) {
+ obj.pass++;
+ }
+ }
+ }
+
+ obj.duration += suite.duration;
+
+ if (suite.childSuites.length > 0) {
+ for (const suiteItem of suite.childSuites) {
+ this.traversalResults(suiteItem, obj, breakOnError);
+ }
+ }
+ }
+
+ async setSuiteResults(suite, error, coreContext) {
+ if (suite.childSuites.length === 0 && suite.specs.length === 0) {
+ return obj;
+ }
+ if (suite.specs.length > 0) {
+ const specService = coreContext.getDefaultService('spec');
+ for (const specItem of suite.specs) {
+ specService.setCurrentRunningSpec(specItem);
+ if (error instanceof AssertException) {
+ specItem.fail = error;
+ } else {
+ specItem.error = error;
+ }
+ await coreContext.fireEvents('spec', 'specStart', specItem);
+ await coreContext.fireEvents('spec', 'specDone', specItem);
+ }
+ }
+ if (suite.childSuites.length > 0) {
+ for (const suiteItem of suite.childSuites) {
+ await this.setSuiteResults(suiteItem, error, coreContext);
+ }
+ }
+ }
+
+ getSummary() {
+ let suiteService = this.coreContext.getDefaultService('suite');
+ let rootSuite = suiteService.rootSuite;
+ const specService = this.coreContext.getDefaultService('spec');
+ const configService = this.coreContext.getDefaultService('config');
+ let breakOnError = configService.isBreakOnError();
+ let isError = specService.getStatus();
+ let isBreaKOnError = breakOnError && isError;
+ let obj = {total: 0, failure: 0, error: 0, pass: 0, ignore: 0, duration: 0};
+ for (const suiteItem of rootSuite.childSuites) {
+ this.traversalResults(suiteItem, obj, isBreaKOnError);
+ }
+ obj.ignore = obj.total - obj.pass - obj.failure - obj.error;
+ return obj;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ }
+
+ traversalSuites(suite, obj, configService) {
+ if (suite.childSuites.length === 0 && suite.specs.length === 0) {
+ return [];
+ }
+ if (suite.specs.length > 0) {
+ let itArray = [];
+ for (const itItem of suite['specs']) {
+ if (!configService.filterDesc(suite.description, itItem.description, itItem.fi, null)) {
+ itArray.push({'itName': itItem.description});
+ }
+ }
+ obj[suite.description] = itArray;
+ }
+
+ if (suite.childSuites.length > 0) {
+ let suiteArray = [];
+ for (const suiteItem of suite.childSuites) {
+ let suiteObj = {};
+ this.traversalSuites(suiteItem, suiteObj, configService);
+ if (!configService.filterSuite(suiteItem.description)) {
+ suiteArray.push(suiteObj);
+ }
+ }
+ obj.suites = suiteArray;
+ }
+ }
+
+ async dryRun(abilityDelegator) {
+ const configService = this.coreContext.getDefaultService('config');
+ let testSuitesObj = {};
+ let suitesArray = [];
+ for (const suiteItem of this.rootSuite.childSuites) {
+ let obj = {};
+ this.traversalSuites(suiteItem, obj, configService);
+ if (!configService.filterSuite(suiteItem.description)) {
+ suitesArray.push(obj);
+ }
+ }
+ testSuitesObj['suites'] = suitesArray;
+
+ let strJson = JSON.stringify(testSuitesObj);
+ let strLen = strJson.length;
+ let maxLen = 500;
+ let maxCount = Math.floor(strLen / maxLen);
+
+ for (let count = 0; count <= maxCount; count++) {
+ await SysTestKit.print(strJson.substring(count * maxLen, (count + 1) * maxLen));
+ }
+ console.info(`${TAG}dryRun print success`);
+ abilityDelegator.finishTest('dry run finished!!!', 0, () => { });
+ }
+
+ execute() {
+ const configService = this.coreContext.getDefaultService('config');
+ if (configService.filterValid.length !== 0) {
+ this.coreContext.fireEvents('task', 'incorrectFormat');
+ return;
+ }
+
+ if (configService.isRandom() && this.rootSuite.childSuites.length > 0) {
+ this.rootSuite.childSuites.sort(function () {
+ return Math.random().toFixed(1) > 0.5 ? -1 : 1;
+ });
+ this.currentRunningSuite = this.rootSuite.childSuites[0];
+ }
+
+ if (configService.isSupportAsync()) {
+ let asyncExecute = async () => {
+ await this.coreContext.fireEvents('task', 'taskStart');
+ await this.rootSuite.asyncRun(this.coreContext);
+ };
+ asyncExecute().then(async () => {
+ await this.coreContext.fireEvents('task', 'taskDone');
+ });
+ } else {
+ this.coreContext.fireEvents('task', 'taskStart');
+ this.rootSuite.run(this.coreContext);
+ this.coreContext.fireEvents('task', 'taskDone');
+ }
+ }
+
+ apis() {
+ const _this = this;
+ return {
+ describe: function (desc, func) {
+ return _this.describe(desc, func);
+ },
+ beforeAll: function (func) {
+ return _this.beforeAll(func);
+ },
+ beforeEach: function (func) {
+ return _this.beforeEach(func);
+ },
+ afterAll: function (func) {
+ return _this.afterAll(func);
+ },
+ afterEach: function (func) {
+ return _this.afterEach(func);
+ }
+ };
+ }
+}
+
+SuiteService.Suite = class {
+ constructor(attrs) {
+ this.description = attrs.description || '';
+ this.childSuites = [];
+ this.specs = [];
+ this.beforeAll = [];
+ this.afterAll = [];
+ this.beforeEach = [];
+ this.afterEach = [];
+ this.duration = 0;
+ this.hookError = null;
+ }
+
+ pushSpec(spec) {
+ this.specs.push(spec);
+ }
+
+ removeSpec(desc) {
+ this.specs = this.specs.filter((item, index) => {
+ return item.description !== desc;
+ });
+ }
+
+ getSpecsNum() {
+ return this.specs.length;
+ }
+
+ isRun(coreContext) {
+ const configService = coreContext.getDefaultService('config');
+ const suiteService = coreContext.getDefaultService('suite');
+ const specService = coreContext.getDefaultService('spec');
+ let breakOnError = configService.isBreakOnError();
+ let isError = specService.getStatus();
+ return breakOnError && isError;
+ }
+
+ run(coreContext) {
+ const suiteService = coreContext.getDefaultService('suite');
+ suiteService.setCurrentRunningSuite(this);
+ if (this.description !== '') {
+ coreContext.fireEvents('suite', 'suiteStart', this);
+ }
+ this.runHookFunc('beforeAll');
+ if (this.specs.length > 0) {
+ const configService = coreContext.getDefaultService('config');
+ if (configService.isRandom()) {
+ this.specs.sort(function () {
+ return Math.random().toFixed(1) > 0.5 ? -1 : 1;
+ });
+ }
+ for (let spec in this.specs) {
+ let isBreakOnError = this.isRun(coreContext);
+ if (isBreakOnError) {
+ break;
+ }
+ this.runHookFunc('beforeEach');
+ spec.run(coreContext);
+ this.runHookFunc('afterEach');
+ }
+ }
+ if (this.childSuites.length > 0) {
+ for (let suite in this.childSuites) {
+ let isBreakOnError = this.isRun(coreContext);
+ if (isBreakOnError) {
+ break;
+ }
+ suite.run(coreContext);
+ suiteService.setCurrentRunningSuite(suite);
+ }
+ }
+ this.runHookFunc('afterAll');
+ if (this.description !== '') {
+ coreContext.fireEvents('suite', 'suiteDone');
+ }
+ }
+
+ async asyncRunSpecs(coreContext) {
+ const configService = coreContext.getDefaultService('config');
+ if (configService.isRandom()) {
+ this.specs.sort(function () {
+ return Math.random().toFixed(1) > 0.5 ? -1 : 1;
+ });
+ }
+ const specService = coreContext.getDefaultService('spec');
+ for (let specItem of this.specs) {
+ specService.setCurrentRunningSpec(specItem);
+ // 遇错即停模式,发现用例有问题,直接返回,不在执行后面的it
+ let isBreakOnError = this.isRun(coreContext);
+ if (isBreakOnError) {
+ console.log("break description :" + this.description);
+ break;
+ }
+ await coreContext.fireEvents('spec', 'specStart', specItem);
+ try {
+ await this.runAsyncHookFunc('beforeEach');
+ await specItem.asyncRun(coreContext);
+ await this.runAsyncHookFunc('afterEach');
+ } catch (e) {
+ console.error(`${TAG}${e?.stack}`);
+ if (e instanceof AssertException) {
+ specItem.fail = e;
+ } else {
+ specItem.error = e;
+ }
+ specService.setStatus(true);
+ }
+ specItem.setResult();
+ await coreContext.fireEvents('spec', 'specDone', specItem);
+ specService.setCurrentRunningSpec(null);
+ }
+ }
+
+ async asyncRunChildSuites(coreContext) {
+ for (let i = 0; i < this.childSuites.length; i++) {
+ // 遇错即停模式, 发现用例有问题,直接返回,不在执行后面的description
+ let isBreakOnError = this.isRun(coreContext);
+ if (isBreakOnError) {
+ console.log(`${TAG}break description : ${this.description}`);
+ break;
+ }
+ await this.childSuites[i].asyncRun(coreContext);
+ }
+ }
+
+ async asyncRun(coreContext) {
+ const suiteService = coreContext.getDefaultService('suite');
+ const specService = coreContext.getDefaultService('spec');
+
+ suiteService.setCurrentRunningSuite(this);
+ suiteService.suitesStack.push(this);
+ if (this.description !== '') {
+ await coreContext.fireEvents('suite', 'suiteStart', this);
+ }
+
+ try {
+ await this.runAsyncHookFunc('beforeAll');
+ } catch (error) {
+ console.error(`${TAG}${error?.stack}`);
+ this.hookError = error;
+ }
+
+ if (this.hookError !== null) {
+ specService.setStatus(true);
+ await suiteService.setSuiteResults(this, this.hookError, coreContext);
+ }
+
+ if (this.specs.length > 0 && this.hookError === null) {
+ await this.asyncRunSpecs(coreContext);
+ }
+
+ if (this.childSuites.length > 0 && this.hookError === null) {
+ await this.asyncRunChildSuites(coreContext);
+ }
+
+ try {
+ await this.runAsyncHookFunc('afterAll');
+ } catch (error) {
+ console.error(`${TAG}${error?.stack}`);
+ this.hookError = error;
+ specService.setStatus(true);
+ }
+
+ if (this.description !== '') {
+ await coreContext.fireEvents('suite', 'suiteDone');
+ let childSuite = suiteService.suitesStack.pop();
+ if (suiteService.suitesStack.length === 0) {
+ suiteService.suitesStack.push(childSuite);
+ }
+ if (suiteService.suitesStack.length > 1) {
+ suiteService.setCurrentRunningSuite(suiteService.suitesStack.pop());
+ } else {
+ let currentRunningSuite = suiteService.suitesStack.pop();
+ suiteService.setCurrentRunningSuite(currentRunningSuite);
+ suiteService.suitesStack.push(currentRunningSuite);
+ }
+ }
+ }
+
+ runHookFunc(hookName) {
+ if (this[hookName] && this[hookName].length > 0) {
+ this[hookName].forEach(func => {
+ try {
+ func();
+ } catch (e) {
+ console.error(`${TAG}${e.stack}`);
+ }
+ });
+ }
+ }
+
+ async runAsyncHookFunc(hookName) {
+ for (const hookItem of this[hookName]) {
+ try {
+ await hookItem();
+ } catch (error) {
+ error['message'] += `, error in ${hookName} function`;
+ throw error;
+ }
+
+ }
+ }
+};
+
+class SpecService {
+ constructor(attr) {
+ this.id = attr.id;
+ this.totalTest = 0;
+ this.hasError = false;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ }
+
+ setCurrentRunningSpec(spec) {
+ this.currentRunningSpec = spec;
+ }
+
+ setStatus(obj) {
+ this.hasError = obj;
+ }
+
+ getStatus() {
+ return this.hasError;
+ }
+
+ getTestTotal() {
+ return this.totalTest;
+ }
+
+ getCurrentRunningSpec() {
+ return this.currentRunningSpec;
+ }
+
+ it(desc, filter, func) {
+ const configService = this.coreContext.getDefaultService('config');
+ const currentSuiteName = this.coreContext.getDefaultService('suite').getCurrentRunningSuite().description;
+ if (configService.filterDesc(currentSuiteName, desc, filter, this.coreContext)) {
+ console.info(`${TAG}filter it :${desc}`);
+ } else {
+ let processedFunc = processFunc(this.coreContext, func);
+ const spec = new SpecService.Spec({description: desc, fi: filter, fn: processedFunc});
+ const suiteService = this.coreContext.getDefaultService('suite');
+ if (typeof this.coreContext.getServices('dataDriver') !== 'undefined' && configService['dryRun'] !== 'true') {
+ let specStress = this.coreContext.getServices('dataDriver').dataDriver.getSpecStress(desc);
+ for (let i = 1; i < specStress; i++) {
+ this.totalTest++;
+ suiteService.getCurrentRunningSuite().pushSpec(spec);
+ }
+ }
+
+ // dryRun 状态下不统计压力测试重复数据
+ if (configService['dryRun'] !== 'true') {
+ let stress = configService.getStress(); // 命令配置压力测试
+ console.info(`${TAG}stress length : ${stress}`);
+ for (let i = 1; i < stress; i++) {
+ this.totalTest++;
+ suiteService.getCurrentRunningSuite().pushSpec(spec);
+ }
+ }
+ this.totalTest++;
+ suiteService.getCurrentRunningSuite().pushSpec(spec);
+ }
+ }
+
+ apis() {
+ const _this = this;
+ return {
+ it: function (desc, filter, func) {
+ return _this.it(desc, filter, func);
+ }
+ };
+ }
+}
+
+SpecService.Spec = class {
+ constructor(attrs) {
+ this.description = attrs.description || '';
+ this.fi = attrs.fi;
+ this.fn = attrs.fn || function () {
+ };
+ this.fail = undefined;
+ this.error = undefined;
+ this.duration = 0;
+ this.startTime = 0;
+ this.isExecuted = false; // 当前用例是否执行
+ }
+
+ setResult() {
+ if (this.fail) {
+ this.pass = false;
+ } else {
+ this.pass = true;
+ }
+ }
+
+ run(coreContext) {
+ const specService = coreContext.getDefaultService('spec');
+ specService.setCurrentRunningSpec(this);
+ coreContext.fireEvents('spec', 'specStart', this);
+ this.isExecuted = true;
+ try {
+ let dataDriver = coreContext.getServices('dataDriver');
+ if (typeof dataDriver === 'undefined') {
+ this.fn();
+ } else {
+ let suiteParams = dataDriver.dataDriver.getSuiteParams();
+ let specParams = dataDriver.dataDriver.getSpecParams();
+ console.info(`${TAG}[suite params] ${JSON.stringify(suiteParams)}`);
+ console.info(`${TAG}[spec params] ${JSON.stringify(specParams)}`);
+ if (this.fn.length === 0) {
+ this.fn();
+ } else if (specParams.length === 0) {
+ this.fn(suiteParams);
+ } else {
+ specParams.forEach(paramItem => this.fn(Object.assign({}, paramItem, suiteParams)));
+ }
+ }
+ this.setResult();
+ } catch (e) {
+ this.error = e;
+ specService.setStatus(true);
+ }
+ coreContext.fireEvents('spec', 'specDone', this);
+ }
+
+ async asyncRun(coreContext) {
+ const dataDriver = coreContext.getServices('dataDriver');
+ if (typeof dataDriver === 'undefined') {
+ await this.fn();
+ } else {
+ const suiteParams = dataDriver.dataDriver.getSuiteParams();
+ const specParams = dataDriver.dataDriver.getSpecParams();
+ console.info(`[suite params] ${JSON.stringify(suiteParams)}`);
+ console.info(`[spec params] ${JSON.stringify(specParams)}`);
+ if (this.fn.length === 0) {
+ await this.fn();
+ } else if (specParams.length === 0) {
+ await this.fn(suiteParams);
+ } else {
+ for (const paramItem of specParams) {
+ await this.fn(Object.assign({}, paramItem, suiteParams));
+ }
+ }
+ }
+
+ this.isExecuted = true;
+ }
+
+ filterCheck(coreContext) {
+ const specService = coreContext.getDefaultService('spec');
+ specService.setCurrentRunningSpec(this);
+ return true;
+ }
+};
+
+class ExpectService {
+ constructor(attr) {
+ this.id = attr.id;
+ this.matchers = {};
+ }
+
+ expect(actualValue) {
+ return this.wrapMatchers(actualValue);
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ this.addMatchers(this.basicMatchers());
+ }
+
+ addMatchers(matchers) {
+ for (const matcherName in matchers) {
+ if (Object.prototype.hasOwnProperty.call(matchers, matcherName)) {
+ this.matchers[matcherName] = matchers[matcherName];
+ }
+ }
+ }
+
+ basicMatchers() {
+ return {
+ assertTrue: function (actualValue) {
+ return {
+ pass: (actualValue) === true,
+ message: 'expect true, actualValue is ' + actualValue
+ };
+ },
+ assertEqual: function (actualValue, args) {
+ return {
+ pass: (actualValue) === args[0],
+ expectValue: args[0],
+ message: 'expect ' + actualValue + ' equals ' + args[0]
+ };
+ },
+ assertThrow: function (actual, args) {
+ const result = {
+ pass: false
+ };
+ if (typeof actual !== 'function') {
+ result.message = 'toThrow\'s Actual should be a Function';
+ } else {
+ let hasThrow = false;
+ let throwError;
+ try {
+ actual();
+ } catch (e) {
+ hasThrow = true;
+ throwError = e;
+ }
+ if (!hasThrow) {
+ result.message = 'function did not throw an exception';
+ } else if (throwError && throwError.message === args[0]) {
+ result.pass = true;
+ } else {
+ result.message = `expect to throw ${args[0]} , actual throw ${throwError.message}`;
+ }
+ }
+ return result;
+ }
+ };
+ }
+
+ wrapMatchers(actualValue) {
+ const _this = this;
+ const wrappedMatchers = {
+ // 翻转标识
+ isNot: false,
+
+ // 翻转方法
+ not: function () {
+ this.isNot = true;
+ return this;
+ }
+ };
+ const specService = _this.coreContext.getDefaultService('spec');
+ const currentRunningSpec = specService.getCurrentRunningSpec();
+ const currentRunningSuite = _this.coreContext.getDefaultService('suite').getCurrentRunningSuite();
+ for (const matcherName in this.matchers) {
+ let result = Object.prototype.hasOwnProperty.call(this.matchers, matcherName);
+ if (!result) {
+ continue;
+ }
+ if (matcherName.search('assertPromise') == 0) {
+ wrappedMatchers[matcherName] = async function () {
+ await _this.matchers[matcherName](actualValue, arguments).then(function (result) {
+ if (wrappedMatchers.isNot) {
+ result.pass = !result.pass;
+ }
+ result.actualValue = actualValue;
+ result.checkFunc = matcherName;
+ if (!result.pass) {
+ const assertError = new AssertException(result.message);
+ currentRunningSpec ? currentRunningSpec.fail = assertError : currentRunningSuite.hookError = assertError;
+ throw assertError;
+ }
+ });
+ };
+ } else {
+ wrappedMatchers[matcherName] = function () {
+ const result = _this.matchers[matcherName](actualValue, arguments);
+ if (wrappedMatchers.isNot) {
+ result.pass = !result.pass;
+ }
+ result.actualValue = actualValue;
+ result.checkFunc = matcherName;
+ if (!result.pass) {
+ const assertError = new AssertException(result.message);
+ currentRunningSpec ? currentRunningSpec.fail = assertError : currentRunningSuite.hookError = assertError;
+ throw assertError;
+ }
+ };
+ }
+ }
+ return wrappedMatchers;
+ }
+
+ apis() {
+ const _this = this;
+ return {
+ expect: function (actualValue) {
+ return _this.expect(actualValue);
+ }
+ };
+ }
+}
+
+class ReportService {
+ constructor(attr) {
+ this.id = attr.id;
+ }
+
+ init(coreContext) {
+ this.coreContext = coreContext;
+ this.specService = this.coreContext.getDefaultService('spec');
+ this.suiteService = this.coreContext.getDefaultService('suite');
+ this.duration = 0;
+ }
+
+ taskStart() {
+ console.info(`${TAG}[start] start run suites`);
+ }
+
+ async suiteStart() {
+ console.info(`${TAG}[suite start]${this.suiteService.getCurrentRunningSuite().description}`);
+ }
+
+ async specStart() {
+ console.info(`${TAG}start running case '${this.specService.currentRunningSpec.description}'`);
+ this.index = this.index + 1;
+ let spec = this.specService.currentRunningSpec;
+ spec.startTime = await SysTestKit.getRealTime();
+ }
+
+ async specDone() {
+ let msg = '';
+ let spec = this.specService.currentRunningSpec;
+ let suite = this.suiteService.currentRunningSuite;
+ spec.duration = await SysTestKit.getRealTime() - spec.startTime;
+ suite.duration += spec.duration;
+ if (spec.error) {
+ this.formatPrint('error', spec.description + ' ; consuming ' + spec.duration + 'ms');
+ this.formatPrint('errorDetail', spec.error);
+ } else if (spec.fail) {
+ this.formatPrint('fail', spec.description + ' ; consuming ' + spec.duration + 'ms');
+ this.formatPrint('failDetail', spec.fail?.message);
+ } else {
+ this.formatPrint('pass', spec.description + ' ; consuming ' + spec.duration + 'ms');
+ }
+ this.formatPrint(this.specService.currentRunningSpec.error, msg);
+ }
+
+ suiteDone() {
+ let suite = this.suiteService.currentRunningSuite;
+ let message = suite.hookError ? `, ${suite.hookError?.message}` : '';
+ console.info(`[suite end] ${suite.description} consuming ${suite.duration} ms${message}`);
+ }
+
+ taskDone() {
+ let msg = '';
+ let summary = this.suiteService.getSummary();
+ msg = 'total cases:' + summary.total + ';failure ' + summary.failure + ',' + 'error ' + summary.error;
+ msg += ',pass ' + summary.pass + '; consuming ' + summary.duration + 'ms';
+ console.info(`${TAG}${msg}`);
+ console.info(`${TAG}[end] run suites end`);
+ }
+
+ incorrectFormat() {
+ if (this.coreContext.getDefaultService('config').filterValid.length !== 0) {
+ this.coreContext.getDefaultService('config').filterValid.forEach(function (item) {
+ console.info(`${TAG}this param ${item} is invalid`);
+ });
+ }
+ }
+
+ formatPrint(type, msg) {
+ switch (type) {
+ case 'pass':
+ console.info(`${TAG}[pass]${msg}`);
+ break;
+ case 'fail':
+ console.info(`${TAG}[fail]${msg}`);
+ break;
+ case 'failDetail':
+ console.info(`${TAG}[failDetail]${msg}`);
+ break;
+ case 'error':
+ console.info(`${TAG}[error]${msg}`);
+ break;
+ case 'errorDetail':
+ console.info(`${TAG}[errorDetail]${msg}`);
+ break;
+ }
+ }
+
+ sleep(numberMillis) {
+ var now = new Date();
+ var exitTime = now.getTime() + numberMillis;
+ while (true) {
+ now = new Date();
+ if (now.getTime() > exitTime) {
+ return;
+ }
+ }
+ }
+}
+
+export {
+ SuiteService,
+ SpecService,
+ ExpectService,
+ ReportService
+};
diff --git a/product/phone/oh-package-lock.json5 b/product/phone/oh-package-lock.json5
new file mode 100644
index 0000000000000000000000000000000000000000..545f3320cc73bf737b0e6566f1f1f3224fc85abc
--- /dev/null
+++ b/product/phone/oh-package-lock.json5
@@ -0,0 +1,25 @@
+{
+ "meta": {
+ "stableOrder": true
+ },
+ "lockfileVersion": 3,
+ "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
+ "specifiers": {
+ "@ohos/common@../../common": "@ohos/common@../../common",
+ "@ohos/recorder@../../feature/recorder": "@ohos/recorder@../../feature/recorder"
+ },
+ "packages": {
+ "@ohos/common@../../common": {
+ "name": "@ohos/common",
+ "version": "1.0.0",
+ "resolved": "../../common",
+ "registryType": "local"
+ },
+ "@ohos/recorder@../../feature/recorder": {
+ "name": "@ohos/recorder",
+ "version": "1.0.0",
+ "resolved": "../../feature/recorder",
+ "registryType": "local"
+ }
+ }
+}
\ No newline at end of file
diff --git a/product/phone/oh-package.json5 b/product/phone/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..19035ebde64ac71b68b49a9b05b26b29d47bdba1
--- /dev/null
+++ b/product/phone/oh-package.json5
@@ -0,0 +1,12 @@
+{
+ "license": "ISC",
+ "devDependencies": {},
+ "name": "phone",
+ "description": "example description",
+ "version": "1.0.0",
+ "dynamicDependencies": {},
+ "dependencies": {
+ "@ohos/recorder": "file:../../feature/recorder",
+ "@ohos/common": "file:../../common"
+ }
+}
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/common/.gitignore b/product/phone/oh_modules/@ohos/common/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4f9a973815d0b5e49bc8547681a6b4bc7a178d12
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/.gitignore
@@ -0,0 +1,3 @@
+/node_modules
+/.preview
+/build
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/common/BuildProfile.ets b/product/phone/oh_modules/@ohos/common/BuildProfile.ets
new file mode 100644
index 0000000000000000000000000000000000000000..3a501e5ddee8ea6d28961648fc7dd314a5304bd4
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/BuildProfile.ets
@@ -0,0 +1,17 @@
+/**
+ * Use these variables when you tailor your ArkTS code. They must be of the const type.
+ */
+export const HAR_VERSION = '1.0.0';
+export const BUILD_MODE_NAME = 'debug';
+export const DEBUG = true;
+export const TARGET_NAME = 'default';
+
+/**
+ * BuildProfile Class is used only for compatibility purposes.
+ */
+export default class BuildProfile {
+ static readonly HAR_VERSION = HAR_VERSION;
+ static readonly BUILD_MODE_NAME = BUILD_MODE_NAME;
+ static readonly DEBUG = DEBUG;
+ static readonly TARGET_NAME = TARGET_NAME;
+}
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/common/build-profile.json5 b/product/phone/oh_modules/@ohos/common/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..7374b5c13faa1f45347034d15c09cbc09a8ab154
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/build-profile.json5
@@ -0,0 +1,17 @@
+{
+ "apiType": "stageMode",
+ "buildOption": {
+ },
+ "buildOptionSet": [
+ {
+ "name": "release",
+ "arkOptions": {
+ "obfuscation": {
+ "ruleOptions": {
+ "enable": false,
+ }
+ }
+ }
+ },
+ ]
+}
diff --git a/product/phone/oh_modules/@ohos/common/hvigorfile.js b/product/phone/oh_modules/@ohos/common/hvigorfile.js
new file mode 100644
index 0000000000000000000000000000000000000000..42ed4b4a54a873e2b53441556aae93fab24b794f
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/hvigorfile.js
@@ -0,0 +1,3 @@
+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
+module.exports = require('@ohos/hvigor-ohos-plugin').harTasks
+
diff --git a/product/phone/oh_modules/@ohos/common/index.ets b/product/phone/oh_modules/@ohos/common/index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..af9c605b34eec7395760f18018aea72ecbd1e703
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/index.ets
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { default as ConfigData } from './src/main/ets/utils/ConfigData'
+
+export { default as Util } from './src/main/ets/utils/Util'
+
+export { default as LogUtil } from './src/main/ets/utils/LogUtil'
diff --git a/product/phone/oh_modules/@ohos/common/oh-package.json5 b/product/phone/oh_modules/@ohos/common/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..3159c134e8893daf7afdf1dc73ed683c7ee24fc2
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/oh-package.json5
@@ -0,0 +1,12 @@
+{
+ "license": "ISC",
+ "types": "",
+ "devDependencies": {},
+ "name": "@ohos/common",
+ "description": "a npm package which contains arkUI2.0 page",
+ "ohos": {
+ "org": ""
+ },
+ "main": "index.ets",
+ "version": "1.0.0",
+}
diff --git a/product/phone/oh_modules/@ohos/common/package.json b/product/phone/oh_modules/@ohos/common/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..dfbf6f7a0611aa4c4fa5f81337f132a4f4a9a694
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/package.json
@@ -0,0 +1,16 @@
+{
+ "license": "ISC",
+ "types": "",
+ "devDependencies": {},
+ "name": "@ohos/common",
+ "description": "a npm package which contains arkUI2.0 page",
+ "ohos": {
+ "org": ""
+ },
+ "main": "src/main/ets/components/MainPage/MainPage.ets",
+ "repository": {},
+ "version": "1.0.0",
+ "dependencies": {
+ "@ohos/hap": "^3.0.0"
+ }
+}
diff --git a/product/phone/oh_modules/@ohos/common/src/main/ets/utils/ConfigData.ets b/product/phone/oh_modules/@ohos/common/src/main/ets/utils/ConfigData.ets
new file mode 100644
index 0000000000000000000000000000000000000000..728136a483d65992eec74b7fd766c0e7792b66cb
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/src/main/ets/utils/ConfigData.ets
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export class ConfigData {
+ WH_100_100 = '100%';
+ WH_50_100 = '50%';
+ WH_40_100 = '40%';
+ WH_20_100 = '20%';
+}
+
+let configData = new ConfigData();
+
+export default configData as ConfigData;
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/common/src/main/ets/utils/LogUtil.ts b/product/phone/oh_modules/@ohos/common/src/main/ets/utils/LogUtil.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bbead9dd9befd61c6caee01842404061533ef8aa
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/src/main/ets/utils/LogUtil.ts
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import HiLog from "@ohos.hilog";
+
+const DOMAIN = 0x0500;
+const TAG = "[Recorder]";
+
+/**
+ * log package tool class
+ */
+export default class LogUtil {
+ static debug(msg): void {
+ HiLog.debug(DOMAIN, TAG, msg);
+ }
+
+ static log(msg): void {
+ HiLog.info(DOMAIN, TAG, msg);
+ }
+
+ static info(msg): void {
+ HiLog.info(DOMAIN, TAG, msg);
+ }
+
+ static warn(msg): void {
+ HiLog.warn(DOMAIN, TAG, msg);
+ }
+
+ static error(msg): void {
+ HiLog.error(DOMAIN, TAG, msg);
+ }
+}
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/common/src/main/ets/utils/Util.ets b/product/phone/oh_modules/@ohos/common/src/main/ets/utils/Util.ets
new file mode 100644
index 0000000000000000000000000000000000000000..d7ff0707252d2bb0d89e37c144e7fdfab82fb52e
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/src/main/ets/utils/Util.ets
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default class Util {
+
+ /**
+ * Time format is converted to seconds
+ *
+ * @param timestamp
+ * @param hasHour
+ */
+ static timeFormat(timestamp: number, hasHour: boolean = true): string {
+ if (timestamp < 0) {
+ return "";
+ }
+ let timeStr = "";
+ let hour = Math.floor(timestamp % (24 * 60 * 60 * 1000) / (60 * 60 * 1000));
+ if (hasHour || hour > 0) {
+ timeStr += Util.addZero(hour) + ":";
+ }
+ let min = Math.floor(timestamp % (60 * 60 * 1000) / (60 * 1000));
+ timeStr += Util.addZero(min) + ":";
+ let sec = Math.floor(timestamp % (60 * 1000) / 1000);
+ timeStr += Util.addZero(sec);
+ return timeStr;
+ }
+
+ /**
+ * Time format is converted to milliseconds
+ *
+ * @param timestamp
+ */
+ static timeFormatMs(timestamp: number): string {
+ if (timestamp <= 0) {
+ return "00:00.00";
+ }
+ let timeStr = "";
+ let hour = Math.floor(timestamp % (24 * 60 * 60 * 1000) / (60 * 60 * 1000));
+ if (hour > 0) {
+ timeStr += Util.addZero(hour) + ":";
+ }
+ let min = Math.floor(timestamp % (60 * 60 * 1000) / (60 * 1000));
+ timeStr += Util.addZero(min) + ":";
+ let sec = Math.floor(timestamp % (60 * 1000) / 1000);
+ timeStr += Util.addZero(sec);
+ if (hour < 1) {
+ let mSec = Math.floor(timestamp % 1000 / 10);
+ timeStr += "." + Util.addZero(mSec);
+ }
+ return timeStr;
+ }
+
+ /**
+ * Gets the date at the specified time
+ *
+ * @param date
+ */
+ static getDateFormat(date: number): string {
+ let nowDate = new Date(date);
+ return nowDate.getFullYear() + "/" + Util.addZero(nowDate.getMonth() + 1) + "/" + Util.addZero(nowDate.getDate());
+ }
+
+ /**
+ * Gets the hour, minute and second of the specified time
+ *
+ * @param date
+ */
+ static getTimeFormat(date: number): string {
+ let nowDate = new Date(date);
+ return Util.addZero(nowDate.getHours()) + ":" + Util.addZero(nowDate.getMinutes()) + ":" + Util.addZero(nowDate.getSeconds());
+ }
+
+ /**
+ * Gets the current time date
+ */
+ static getDate(): string {
+ let nowDate = new Date();
+ return nowDate.getFullYear() + Util.addZero(nowDate.getMonth() + 1) + Util.addZero(nowDate.getDate());
+ }
+
+ /**
+ * Gets the hour, minute and second of the current time
+ */
+ static getTime(): string {
+ let nowDate = new Date();
+ return Util.addZero(nowDate.getHours()) + Util.addZero(nowDate.getMinutes()) + Util.addZero(nowDate.getSeconds());
+ }
+
+ /**
+ * If the number is less than 10, add "0".
+ *
+ * @param num
+ */
+ static addZero(num: number): string{
+ return (num < 10 ? "0" + num : num).toString();
+ }
+}
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/common/src/main/module.json5 b/product/phone/oh_modules/@ohos/common/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..56a91a87ba3ea303b57e4b8e5f405e9d6d2a800a
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/src/main/module.json5
@@ -0,0 +1,11 @@
+{
+ "module": {
+ "name": "common",
+ "type": "har",
+ "deviceTypes": [
+ "default",
+ "tablet"
+ ],
+ "uiSyntax": "ets"
+ }
+}
diff --git a/product/phone/oh_modules/@ohos/common/src/main/resources/base/element/color.json b/product/phone/oh_modules/@ohos/common/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..ffe7272ac3029e44fd8fe56844ac7a59808be8a2
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/src/main/resources/base/element/color.json
@@ -0,0 +1,32 @@
+{
+ "color": [
+ {
+ "name": "white",
+ "value": "#FFFFFF"
+ },
+ {
+ "name": "background_color",
+ "value": "#F1F3F5"
+ },
+ {
+ "name": "shadow_color",
+ "value": "#11000000"
+ },
+ {
+ "name": "pointer_color",
+ "value": "#007DFF"
+ },
+ {
+ "name": "warn_color",
+ "value": "#FF595A"
+ },
+ {
+ "name": "hint_color",
+ "value": "#007DFF"
+ },
+ {
+ "name": "text_color",
+ "value": "#182431"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/common/src/main/resources/base/element/string.json b/product/phone/oh_modules/@ohos/common/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..2375b2de43748384262b8e07fa36405169d878c8
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/src/main/resources/base/element/string.json
@@ -0,0 +1,56 @@
+{
+ "string": [
+ {
+ "name": "page_show",
+ "value": "page from npm package"
+ },
+ {
+ "name": "title",
+ "value": "录音机"
+ },
+ {
+ "name": "search_recording_files",
+ "value": "搜索录音文件"
+ },
+ {
+ "name": "mark",
+ "value": "标记"
+ },
+ {
+ "name": "pause",
+ "value": "暂停"
+ },
+ {
+ "name": "continue_record",
+ "value": "继续"
+ },
+ {
+ "name": "predict_hint",
+ "value": "预计还能录制10小时以上"
+ },
+ {
+ "name": "delete_hint",
+ "value": "是否删除此条录音?"
+ },
+ {
+ "name": "cancel",
+ "value": "取消"
+ },
+ {
+ "name": "delete",
+ "value": "删除"
+ },
+ {
+ "name": "has_call_hint",
+ "value": "通话状态无法录音"
+ },
+ {
+ "name": "recording_hint",
+ "value": "录音机正在录音"
+ },
+ {
+ "name": "suspend_record_hint",
+ "value": "录音机暂停录音"
+ }
+ ]
+}
diff --git a/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/bg_record.png b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/bg_record.png
new file mode 100644
index 0000000000000000000000000000000000000000..41c12ccb5bb90cd9c05508690ca0b88f33e96008
Binary files /dev/null and b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/bg_record.png differ
diff --git a/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_back.svg b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_back.svg
new file mode 100644
index 0000000000000000000000000000000000000000..6f7f039226e90d3ef91b0e83c4ad29236858e868
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_back.svg
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_add.svg b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_add.svg
new file mode 100644
index 0000000000000000000000000000000000000000..3ec94e4b1e5f198844f5136dc14c9ff00ab95887
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_add.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_enhance.svg b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_enhance.svg
new file mode 100644
index 0000000000000000000000000000000000000000..14a0ba5bbea05082e4659a124dc89b79f523509b
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_enhance.svg
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_mark.svg b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_mark.svg
new file mode 100644
index 0000000000000000000000000000000000000000..330eda737a418114cc3389b4c14cbcada67ec5e9
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_mark.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_play.svg b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_play.svg
new file mode 100644
index 0000000000000000000000000000000000000000..4a6c56994bd7736e81307833789775d51b71cf6c
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_play.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_record.svg b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_record.svg
new file mode 100644
index 0000000000000000000000000000000000000000..c8f7906490d4e4ae103cf1d35fd3e5c4c55f27f0
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_record.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_stop.svg b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_stop.svg
new file mode 100644
index 0000000000000000000000000000000000000000..02964494e7ad6466ce03c368befe5a7e3c1ed01b
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_stop.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_suspend.svg b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_suspend.svg
new file mode 100644
index 0000000000000000000000000000000000000000..bf6f0ea2eabe25b77ef0bed04d52cb1e6ac6bb0b
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_suspend.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_play.svg b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_play.svg
new file mode 100644
index 0000000000000000000000000000000000000000..34c0e947768885c982a4031b2df92c1fe7b014ab
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_play.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_search.svg b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_search.svg
new file mode 100644
index 0000000000000000000000000000000000000000..1b2a8aa35dc2c2ea6b47fad1fdfe319947701b43
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_search.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_stop.svg b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_stop.svg
new file mode 100644
index 0000000000000000000000000000000000000000..2b7ceaa1d1b8a10b1b18f0a1515477874df4b357
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_stop.svg
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/public_more.svg b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/public_more.svg
new file mode 100644
index 0000000000000000000000000000000000000000..400c3ef1abe1ebe1b0637b20c1c4b9711812b41e
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/common/src/main/resources/base/media/public_more.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/.gitignore b/product/phone/oh_modules/@ohos/recorder/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4f9a973815d0b5e49bc8547681a6b4bc7a178d12
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/.gitignore
@@ -0,0 +1,3 @@
+/node_modules
+/.preview
+/build
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/BuildProfile.ets b/product/phone/oh_modules/@ohos/recorder/BuildProfile.ets
new file mode 100644
index 0000000000000000000000000000000000000000..3a501e5ddee8ea6d28961648fc7dd314a5304bd4
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/BuildProfile.ets
@@ -0,0 +1,17 @@
+/**
+ * Use these variables when you tailor your ArkTS code. They must be of the const type.
+ */
+export const HAR_VERSION = '1.0.0';
+export const BUILD_MODE_NAME = 'debug';
+export const DEBUG = true;
+export const TARGET_NAME = 'default';
+
+/**
+ * BuildProfile Class is used only for compatibility purposes.
+ */
+export default class BuildProfile {
+ static readonly HAR_VERSION = HAR_VERSION;
+ static readonly BUILD_MODE_NAME = BUILD_MODE_NAME;
+ static readonly DEBUG = DEBUG;
+ static readonly TARGET_NAME = TARGET_NAME;
+}
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/build-profile.json5 b/product/phone/oh_modules/@ohos/recorder/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..35dff6d53cb3a241f8de4fb68bd01d38ade0f108
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/build-profile.json5
@@ -0,0 +1,5 @@
+{
+ "apiType": "stageMode",
+ "buildOption": {
+ }
+}
diff --git a/product/phone/oh_modules/@ohos/recorder/hvigorfile.js b/product/phone/oh_modules/@ohos/recorder/hvigorfile.js
new file mode 100644
index 0000000000000000000000000000000000000000..42ed4b4a54a873e2b53441556aae93fab24b794f
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/hvigorfile.js
@@ -0,0 +1,3 @@
+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
+module.exports = require('@ohos/hvigor-ohos-plugin').harTasks
+
diff --git a/product/phone/oh_modules/@ohos/recorder/index.ets b/product/phone/oh_modules/@ohos/recorder/index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..98c643021853a081786f585ce73e679d2f0a3df7
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/index.ets
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { RecordController, RecordState } from './src/main/ets/controller/RecordController'
+
+export { default as MediaController } from './src/main/ets/controller/MediaController'
+
+export { AudioController, AudioState } from './src/main/ets/controller/AudioController'
+
+export { StateController, ControlState } from './src/main/ets/controller/StateController'
+
+export { RecordData } from './src/main/ets/model/RecordData'
diff --git a/product/phone/oh_modules/@ohos/recorder/oh-package-lock.json5 b/product/phone/oh_modules/@ohos/recorder/oh-package-lock.json5
new file mode 100644
index 0000000000000000000000000000000000000000..71fb2aa27ea03ee139d0c1365fbfd5ab52c7931d
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh-package-lock.json5
@@ -0,0 +1,18 @@
+{
+ "meta": {
+ "stableOrder": true
+ },
+ "lockfileVersion": 3,
+ "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
+ "specifiers": {
+ "@ohos/common@../../common": "@ohos/common@../../common"
+ },
+ "packages": {
+ "@ohos/common@../../common": {
+ "name": "@ohos/common",
+ "version": "1.0.0",
+ "resolved": "../../common",
+ "registryType": "local"
+ }
+ }
+}
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/oh-package.json5 b/product/phone/oh_modules/@ohos/recorder/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..c395a2849c8e98e829d405d584bcb87dc6cfa72b
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh-package.json5
@@ -0,0 +1,13 @@
+{
+ "license": "ISC",
+ "types": "",
+ "devDependencies": {
+ "@ohos/common": "file:../../common"
+ },
+ "name": "@ohos/recorder",
+ "description": "a npm package which contains arkUI2.0 page",
+ "main": "index.ets",
+ "version": "1.0.0",
+ "dynamicDependencies": {},
+ "dependencies": {}
+}
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/.gitignore b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4f9a973815d0b5e49bc8547681a6b4bc7a178d12
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/.gitignore
@@ -0,0 +1,3 @@
+/node_modules
+/.preview
+/build
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/BuildProfile.ets b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/BuildProfile.ets
new file mode 100644
index 0000000000000000000000000000000000000000..3a501e5ddee8ea6d28961648fc7dd314a5304bd4
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/BuildProfile.ets
@@ -0,0 +1,17 @@
+/**
+ * Use these variables when you tailor your ArkTS code. They must be of the const type.
+ */
+export const HAR_VERSION = '1.0.0';
+export const BUILD_MODE_NAME = 'debug';
+export const DEBUG = true;
+export const TARGET_NAME = 'default';
+
+/**
+ * BuildProfile Class is used only for compatibility purposes.
+ */
+export default class BuildProfile {
+ static readonly HAR_VERSION = HAR_VERSION;
+ static readonly BUILD_MODE_NAME = BUILD_MODE_NAME;
+ static readonly DEBUG = DEBUG;
+ static readonly TARGET_NAME = TARGET_NAME;
+}
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/build-profile.json5 b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..7374b5c13faa1f45347034d15c09cbc09a8ab154
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/build-profile.json5
@@ -0,0 +1,17 @@
+{
+ "apiType": "stageMode",
+ "buildOption": {
+ },
+ "buildOptionSet": [
+ {
+ "name": "release",
+ "arkOptions": {
+ "obfuscation": {
+ "ruleOptions": {
+ "enable": false,
+ }
+ }
+ }
+ },
+ ]
+}
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/hvigorfile.js b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/hvigorfile.js
new file mode 100644
index 0000000000000000000000000000000000000000..42ed4b4a54a873e2b53441556aae93fab24b794f
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/hvigorfile.js
@@ -0,0 +1,3 @@
+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
+module.exports = require('@ohos/hvigor-ohos-plugin').harTasks
+
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/index.ets b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..af9c605b34eec7395760f18018aea72ecbd1e703
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/index.ets
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { default as ConfigData } from './src/main/ets/utils/ConfigData'
+
+export { default as Util } from './src/main/ets/utils/Util'
+
+export { default as LogUtil } from './src/main/ets/utils/LogUtil'
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/oh-package.json5 b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..3159c134e8893daf7afdf1dc73ed683c7ee24fc2
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/oh-package.json5
@@ -0,0 +1,12 @@
+{
+ "license": "ISC",
+ "types": "",
+ "devDependencies": {},
+ "name": "@ohos/common",
+ "description": "a npm package which contains arkUI2.0 page",
+ "ohos": {
+ "org": ""
+ },
+ "main": "index.ets",
+ "version": "1.0.0",
+}
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/package.json b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..dfbf6f7a0611aa4c4fa5f81337f132a4f4a9a694
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/package.json
@@ -0,0 +1,16 @@
+{
+ "license": "ISC",
+ "types": "",
+ "devDependencies": {},
+ "name": "@ohos/common",
+ "description": "a npm package which contains arkUI2.0 page",
+ "ohos": {
+ "org": ""
+ },
+ "main": "src/main/ets/components/MainPage/MainPage.ets",
+ "repository": {},
+ "version": "1.0.0",
+ "dependencies": {
+ "@ohos/hap": "^3.0.0"
+ }
+}
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/ets/utils/ConfigData.ets b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/ets/utils/ConfigData.ets
new file mode 100644
index 0000000000000000000000000000000000000000..728136a483d65992eec74b7fd766c0e7792b66cb
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/ets/utils/ConfigData.ets
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export class ConfigData {
+ WH_100_100 = '100%';
+ WH_50_100 = '50%';
+ WH_40_100 = '40%';
+ WH_20_100 = '20%';
+}
+
+let configData = new ConfigData();
+
+export default configData as ConfigData;
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/ets/utils/LogUtil.ts b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/ets/utils/LogUtil.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bbead9dd9befd61c6caee01842404061533ef8aa
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/ets/utils/LogUtil.ts
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import HiLog from "@ohos.hilog";
+
+const DOMAIN = 0x0500;
+const TAG = "[Recorder]";
+
+/**
+ * log package tool class
+ */
+export default class LogUtil {
+ static debug(msg): void {
+ HiLog.debug(DOMAIN, TAG, msg);
+ }
+
+ static log(msg): void {
+ HiLog.info(DOMAIN, TAG, msg);
+ }
+
+ static info(msg): void {
+ HiLog.info(DOMAIN, TAG, msg);
+ }
+
+ static warn(msg): void {
+ HiLog.warn(DOMAIN, TAG, msg);
+ }
+
+ static error(msg): void {
+ HiLog.error(DOMAIN, TAG, msg);
+ }
+}
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/ets/utils/Util.ets b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/ets/utils/Util.ets
new file mode 100644
index 0000000000000000000000000000000000000000..d7ff0707252d2bb0d89e37c144e7fdfab82fb52e
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/ets/utils/Util.ets
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default class Util {
+
+ /**
+ * Time format is converted to seconds
+ *
+ * @param timestamp
+ * @param hasHour
+ */
+ static timeFormat(timestamp: number, hasHour: boolean = true): string {
+ if (timestamp < 0) {
+ return "";
+ }
+ let timeStr = "";
+ let hour = Math.floor(timestamp % (24 * 60 * 60 * 1000) / (60 * 60 * 1000));
+ if (hasHour || hour > 0) {
+ timeStr += Util.addZero(hour) + ":";
+ }
+ let min = Math.floor(timestamp % (60 * 60 * 1000) / (60 * 1000));
+ timeStr += Util.addZero(min) + ":";
+ let sec = Math.floor(timestamp % (60 * 1000) / 1000);
+ timeStr += Util.addZero(sec);
+ return timeStr;
+ }
+
+ /**
+ * Time format is converted to milliseconds
+ *
+ * @param timestamp
+ */
+ static timeFormatMs(timestamp: number): string {
+ if (timestamp <= 0) {
+ return "00:00.00";
+ }
+ let timeStr = "";
+ let hour = Math.floor(timestamp % (24 * 60 * 60 * 1000) / (60 * 60 * 1000));
+ if (hour > 0) {
+ timeStr += Util.addZero(hour) + ":";
+ }
+ let min = Math.floor(timestamp % (60 * 60 * 1000) / (60 * 1000));
+ timeStr += Util.addZero(min) + ":";
+ let sec = Math.floor(timestamp % (60 * 1000) / 1000);
+ timeStr += Util.addZero(sec);
+ if (hour < 1) {
+ let mSec = Math.floor(timestamp % 1000 / 10);
+ timeStr += "." + Util.addZero(mSec);
+ }
+ return timeStr;
+ }
+
+ /**
+ * Gets the date at the specified time
+ *
+ * @param date
+ */
+ static getDateFormat(date: number): string {
+ let nowDate = new Date(date);
+ return nowDate.getFullYear() + "/" + Util.addZero(nowDate.getMonth() + 1) + "/" + Util.addZero(nowDate.getDate());
+ }
+
+ /**
+ * Gets the hour, minute and second of the specified time
+ *
+ * @param date
+ */
+ static getTimeFormat(date: number): string {
+ let nowDate = new Date(date);
+ return Util.addZero(nowDate.getHours()) + ":" + Util.addZero(nowDate.getMinutes()) + ":" + Util.addZero(nowDate.getSeconds());
+ }
+
+ /**
+ * Gets the current time date
+ */
+ static getDate(): string {
+ let nowDate = new Date();
+ return nowDate.getFullYear() + Util.addZero(nowDate.getMonth() + 1) + Util.addZero(nowDate.getDate());
+ }
+
+ /**
+ * Gets the hour, minute and second of the current time
+ */
+ static getTime(): string {
+ let nowDate = new Date();
+ return Util.addZero(nowDate.getHours()) + Util.addZero(nowDate.getMinutes()) + Util.addZero(nowDate.getSeconds());
+ }
+
+ /**
+ * If the number is less than 10, add "0".
+ *
+ * @param num
+ */
+ static addZero(num: number): string{
+ return (num < 10 ? "0" + num : num).toString();
+ }
+}
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/module.json5 b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..56a91a87ba3ea303b57e4b8e5f405e9d6d2a800a
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/module.json5
@@ -0,0 +1,11 @@
+{
+ "module": {
+ "name": "common",
+ "type": "har",
+ "deviceTypes": [
+ "default",
+ "tablet"
+ ],
+ "uiSyntax": "ets"
+ }
+}
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/element/color.json b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..ffe7272ac3029e44fd8fe56844ac7a59808be8a2
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/element/color.json
@@ -0,0 +1,32 @@
+{
+ "color": [
+ {
+ "name": "white",
+ "value": "#FFFFFF"
+ },
+ {
+ "name": "background_color",
+ "value": "#F1F3F5"
+ },
+ {
+ "name": "shadow_color",
+ "value": "#11000000"
+ },
+ {
+ "name": "pointer_color",
+ "value": "#007DFF"
+ },
+ {
+ "name": "warn_color",
+ "value": "#FF595A"
+ },
+ {
+ "name": "hint_color",
+ "value": "#007DFF"
+ },
+ {
+ "name": "text_color",
+ "value": "#182431"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/element/string.json b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..2375b2de43748384262b8e07fa36405169d878c8
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/element/string.json
@@ -0,0 +1,56 @@
+{
+ "string": [
+ {
+ "name": "page_show",
+ "value": "page from npm package"
+ },
+ {
+ "name": "title",
+ "value": "录音机"
+ },
+ {
+ "name": "search_recording_files",
+ "value": "搜索录音文件"
+ },
+ {
+ "name": "mark",
+ "value": "标记"
+ },
+ {
+ "name": "pause",
+ "value": "暂停"
+ },
+ {
+ "name": "continue_record",
+ "value": "继续"
+ },
+ {
+ "name": "predict_hint",
+ "value": "预计还能录制10小时以上"
+ },
+ {
+ "name": "delete_hint",
+ "value": "是否删除此条录音?"
+ },
+ {
+ "name": "cancel",
+ "value": "取消"
+ },
+ {
+ "name": "delete",
+ "value": "删除"
+ },
+ {
+ "name": "has_call_hint",
+ "value": "通话状态无法录音"
+ },
+ {
+ "name": "recording_hint",
+ "value": "录音机正在录音"
+ },
+ {
+ "name": "suspend_record_hint",
+ "value": "录音机暂停录音"
+ }
+ ]
+}
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/bg_record.png b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/bg_record.png
new file mode 100644
index 0000000000000000000000000000000000000000..41c12ccb5bb90cd9c05508690ca0b88f33e96008
Binary files /dev/null and b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/bg_record.png differ
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_back.svg b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_back.svg
new file mode 100644
index 0000000000000000000000000000000000000000..6f7f039226e90d3ef91b0e83c4ad29236858e868
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_back.svg
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_add.svg b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_add.svg
new file mode 100644
index 0000000000000000000000000000000000000000..3ec94e4b1e5f198844f5136dc14c9ff00ab95887
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_add.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_enhance.svg b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_enhance.svg
new file mode 100644
index 0000000000000000000000000000000000000000..14a0ba5bbea05082e4659a124dc89b79f523509b
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_enhance.svg
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_mark.svg b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_mark.svg
new file mode 100644
index 0000000000000000000000000000000000000000..330eda737a418114cc3389b4c14cbcada67ec5e9
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_mark.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_play.svg b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_play.svg
new file mode 100644
index 0000000000000000000000000000000000000000..4a6c56994bd7736e81307833789775d51b71cf6c
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_play.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_record.svg b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_record.svg
new file mode 100644
index 0000000000000000000000000000000000000000..c8f7906490d4e4ae103cf1d35fd3e5c4c55f27f0
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_record.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_stop.svg b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_stop.svg
new file mode 100644
index 0000000000000000000000000000000000000000..02964494e7ad6466ce03c368befe5a7e3c1ed01b
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_stop.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_suspend.svg b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_suspend.svg
new file mode 100644
index 0000000000000000000000000000000000000000..bf6f0ea2eabe25b77ef0bed04d52cb1e6ac6bb0b
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_suspend.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_play.svg b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_play.svg
new file mode 100644
index 0000000000000000000000000000000000000000..34c0e947768885c982a4031b2df92c1fe7b014ab
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_play.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_search.svg b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_search.svg
new file mode 100644
index 0000000000000000000000000000000000000000..1b2a8aa35dc2c2ea6b47fad1fdfe319947701b43
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_search.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_stop.svg b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_stop.svg
new file mode 100644
index 0000000000000000000000000000000000000000..2b7ceaa1d1b8a10b1b18f0a1515477874df4b357
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_stop.svg
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/public_more.svg b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/public_more.svg
new file mode 100644
index 0000000000000000000000000000000000000000..400c3ef1abe1ebe1b0637b20c1c4b9711812b41e
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/public_more.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/package.json b/product/phone/oh_modules/@ohos/recorder/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..83c74cf381e47f923fd3171be67a35594e7224e6
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/package.json
@@ -0,0 +1,16 @@
+{
+ "license": "ISC",
+ "types": "",
+ "devDependencies": {},
+ "name": "@ohos/recorder",
+ "description": "a npm package which contains arkUI2.0 page",
+ "ohos": {
+ "org": ""
+ },
+ "main": "src/main/ets/components/MainPage/MainPage.ets",
+ "repository": {},
+ "version": "1.0.0",
+ "dependencies": {
+ "@ohos/common": "file:../../common"
+ }
+}
diff --git a/product/phone/oh_modules/@ohos/recorder/src/main/ets/controller/AudioController.ets b/product/phone/oh_modules/@ohos/recorder/src/main/ets/controller/AudioController.ets
new file mode 100644
index 0000000000000000000000000000000000000000..2b1cae60bf5f1691912519eeb7df29fd37263f18
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/src/main/ets/controller/AudioController.ets
@@ -0,0 +1,202 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import mediaLibrary from '@ohos.multimedia.mediaLibrary';
+import media from '@ohos.multimedia.media';
+import { LogUtil } from '@ohos/common';
+import { BusinessError, Callback } from '@ohos.base'
+
+export enum AudioState {
+ /**
+ * The initial state
+ */
+ IDLE,
+ /**
+ * Continuously update time starting from IDLE state or PAUSED state
+ */
+ RUNNING,
+ /**
+ * Click Pause from the RUNNING state
+ */
+ PAUSED,
+}
+
+const NOTIFY_INTERVAL_MS = 50;
+const TAG = "AudioController : ";
+
+export class AudioController {
+ private audioPlayer?: media.AVPlayer;
+ private state: string = 'idle';
+ private playFile: string = '';
+ private dataLoad: boolean = false;
+ private currentTimeMs: number = 0;
+ private intervalId: number = -1;
+ private timeUpdateListener?: Callback;
+ private stateUpdateListener?: Callback;
+
+ /**
+ * Set the time update listener
+ *
+ * @param listener
+ */
+ public setTimeUpdateListener(tag: string, timeUpdateListener: Callback): void {
+ LogUtil.info(`${TAG} setTimeUpdateListener`);
+ this.timeUpdateListener = timeUpdateListener;
+ }
+
+ /**
+ * Set the status update listener
+ *
+ * @param listener
+ */
+ public setStateUpdateListener(tag: string, setStateUpdateListener: Callback): void {
+ LogUtil.info(`${TAG} setStateUpdateListener`);
+ this.stateUpdateListener = setStateUpdateListener;
+ }
+
+ /**
+ * Notification time update
+ */
+ private notifyTimeChanges() {
+ if (this.timeUpdateListener) {
+ this.timeUpdateListener(this.currentTimeMs);
+ }
+ }
+
+ /**
+ * Notification of status updates
+ */
+ private async notifyStateChanges() {
+ if (this.stateUpdateListener) {
+ LogUtil.info(`${TAG} state update ${this.state}`);
+ this.stateUpdateListener(this.state);
+ }
+ }
+
+ /**
+ * Initialize the audio player
+ *
+ * @param playSrc
+ * @param callback
+ */
+ async initAudioPlayer(playSrc: string, callback: () => void) {
+ LogUtil.info(`${TAG} initAudioPlayer`);
+ this.playFile = playSrc;
+ this.dataLoad = false;
+ this.release();
+ LogUtil.info(`${TAG} createAudioPlayer`);
+ if (!this.audioPlayer) {
+ return;
+ }
+ try {
+ this.audioPlayer = await media.createAVPlayer();
+ } catch (e) {
+ }
+ this.audioPlayer?.on('stateChange', this.stateChangeListener)
+ }
+
+ private stateChangeListener = async (state: string, reason: media.StateChangeReason) => {
+ if (!this.audioPlayer) {
+ return;
+ }
+ this.state = state;
+ switch (state) {
+ case 'idle' :
+ break;
+ case 'initialized':
+ break;
+ case 'playing':
+ break;
+ case 'prepared':
+ break;
+ case 'paused':
+ break;
+ case 'completed':
+ break;
+ case 'stopped':
+ case 'released':
+ break;
+ }
+ }
+ /**
+ * audioPlayer play
+ */
+ play() {
+ try {
+ if (this.audioPlayer) {
+ this.audioPlayer.play();
+ }
+ } catch (e) {
+ }
+ }
+
+ /**
+ * audioPlayer seek time
+ *
+ * @param timeMs
+ */
+ seek(timeMs: number) {
+ if (this.audioPlayer) {
+ LogUtil.info(`${TAG} audioPlayer time to jump. time:` + timeMs);
+ this.audioPlayer.seek(timeMs);
+ }
+ }
+
+ /**
+ * audioPlayer pause
+ */
+ pause() {
+ if (this.audioPlayer) {
+ LogUtil.info(`${TAG} audioPlayer pause`);
+ this.audioPlayer.pause();
+ }
+ }
+
+ /**
+ * audioPlayer stop
+ */
+ stop() {
+ if ((this.audioPlayer) && this.state != 'idle') {
+ LogUtil.info(`${TAG} audioPlayer stop`);
+ this.state = 'idle';
+ this.audioPlayer.release();
+ this.intervalId = -1;
+ }
+ }
+
+ /**
+ * audioPlayer continue play
+ */
+ continuePlay() {
+ if (this.audioPlayer) {
+ LogUtil.info(`${TAG} audioPlayer continue play`);
+ this.audioPlayer.play();
+ }
+ }
+
+ /**
+ * audioPlayer release
+ */
+ release() {
+ if (this.audioPlayer) {
+ this.currentTimeMs = 0;
+ this.notifyTimeChanges();
+ LogUtil.info(`${TAG} audioPlayer release`);
+ this.audioPlayer.release();
+ this.audioPlayer = undefined;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/src/main/ets/controller/MediaController.ets b/product/phone/oh_modules/@ohos/recorder/src/main/ets/controller/MediaController.ets
new file mode 100644
index 0000000000000000000000000000000000000000..db8262d36fd8eae29ec262333d9b58a25f0b9b12
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/src/main/ets/controller/MediaController.ets
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import mediaLibrary from '@ohos.multimedia.mediaLibrary';
+import { Util } from '@ohos/common';
+import { RecordData } from '../model/RecordData';
+import data_preferences from '@ohos.data.preferences';
+import { LogUtil } from '@ohos/common';
+
+const TAG = 'MediaController : ';
+
+export class MediaController {
+ private mMediaLibrary: mediaLibrary.MediaLibrary = mediaLibrary.getMediaLibrary(globalThis.abilityContext);
+ private preferences?: data_preferences.Preferences;
+
+ constructor() {
+ this.initPreferences();
+ }
+
+ /**
+ * init Preferences
+ */
+ async initPreferences() {
+ LogUtil.info(`${TAG} initPreferences.`);
+ this.preferences = await data_preferences.getPreferences(globalThis.abilityContext, 'myRecorderStore');
+ }
+
+ /**
+ * save File Duration to preferences
+ *
+ * @param name
+ * @param value
+ */
+ async saveFileDuration(name: string, value: number) {
+ LogUtil.info(`${TAG} saveFileDuration. fileName : ${name}. duration:${value}`);
+ if (this.preferences) {
+ await this.preferences.put(name, value);
+ this.preferences.flush();
+ LogUtil.info(`${TAG} save File Duration end.`);
+ }
+ }
+}
+
+export default new MediaController();
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/src/main/ets/controller/RecordController.ets b/product/phone/oh_modules/@ohos/recorder/src/main/ets/controller/RecordController.ets
new file mode 100644
index 0000000000000000000000000000000000000000..ec15a779f0a2967432f910a9e0b4ff8b7cd72c52
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/src/main/ets/controller/RecordController.ets
@@ -0,0 +1,189 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import media from '@ohos.multimedia.media';
+import { LogUtil } from '@ohos/common';
+import Notification from '@ohos.notification';
+import { BusinessError, Callback } from '@ohos.base'
+
+const NOTIFY_INTERVAL_MS = 60;
+const NOTIFY_ID = 10023;
+const TAG = 'RecordController : ';
+
+export enum RecordState {
+ IDLE,
+ RUNNING,
+ PAUSED,
+}
+
+export class RecordController {
+ private beforePauseTime: number = 0;
+ private startTimestamp: number = 0;
+ private notifierId: number = -1;
+ private state: string = '';
+ private config?: media.AVRecorderConfig;
+ private openedFileFd?: number;
+ private currentFilePath?: string;
+ private recorderDuration: number = 0;
+ private currentTimeMs: number = 0;
+ private audioRecorder?: media.AVRecorder;
+ private timeUpdateListener?: Callback;
+ private stateUpdateListener?: Callback;
+
+ /**
+ * Notification time update
+ */
+ private notifyTimeChanges() {
+ if (this.timeUpdateListener) {
+ this.timeUpdateListener(this.currentTimeMs);
+ }
+ }
+
+ /**
+ * Notification of status updates
+ */
+ private async notifyStateChanges() {
+ if (this.stateUpdateListener) {
+ LogUtil.info(`${TAG} state update. ${this.state}`);
+ this.stateUpdateListener(this.state);
+ }
+ }
+
+ /**
+ * Set the time update listener
+ *
+ * @param listener
+ */
+ public setTimeUpdateListener(tag: string, timeUpdateListener: Callback): void {
+ LogUtil.info(`${TAG} setTimeUpdateListener`);
+ this.timeUpdateListener = timeUpdateListener;
+ }
+
+ /**
+ * Set the status update listener
+ *
+ * @param listener
+ */
+ public setStateUpdateListener(tag: string, setStateUpdateListener: Callback): void {
+ LogUtil.info(`${TAG} setStateUpdateListener`);
+ this.stateUpdateListener = setStateUpdateListener;
+ }
+
+ /**
+ * init AudioRecorder
+ */
+ async initAudioRecorder() {
+ LogUtil.info(`${TAG} initAudioRecorder.`);
+ if (!this.audioRecorder) {
+ this.audioRecorder = await media.createAVRecorder();
+ }
+ this.setAVRecorderCallback(this.audioRecorder);
+ }
+
+ private setAVRecorderCallback(avRecorder: media.AVRecorder): void {
+ if (!avRecorder) {
+ return;
+ }
+ avRecorder.on('error', async (err: BusinessError) => {
+
+ });
+ avRecorder.on('stateChange', async (state: string, resaon: media.StateChangeReason) => {
+ this.state = state;
+ switch (state) {
+ case 'idle':
+ break;
+ case 'initialized':
+ break;
+ case 'started':
+ break;
+ case 'prepared':
+ break;
+ case 'paused':
+ break;
+ case 'completed':
+ break;
+ case 'stopped':
+ break;
+ case 'released':
+ break;
+ case 'released':
+ break;
+ default:
+ break
+ }
+ });
+ }
+
+ /**
+ * Gets the sound size of the recording
+ */
+ getSoundVolume() { //todo
+ return Math.random() * 100 + 5;
+ }
+
+ /**
+ * Recorder start
+ *
+ * @param pathName
+ */
+ startRecorder(tag: string, filefd: number, filePath: string, config: media.AVRecorderConfig,
+ recorderStateCallback: Callback, onErrorCallback?: Callback) {
+ if (this.audioRecorder) {
+ this.recorderDuration = 0;
+ this.currentFilePath = filePath;
+ this.config = config;
+ this.openedFileFd = filefd;
+ if (this.audioRecorder.state === 'idle') {
+ this.audioRecorder.prepare(config);
+ } else {
+ this.audioRecorder.reset();
+ }
+ LogUtil.info(`${TAG} audioRecorder prepare.`);
+ ;
+ } else {
+ LogUtil.error(`${TAG} case failed, audioRecorder is null.`);
+ }
+ }
+
+ /**
+ * Recorder pause
+ */
+ pause() {
+ if (this.audioRecorder) {
+ LogUtil.info(`${TAG} audioRecorder pause`);
+ this.audioRecorder.pause();
+ }
+ }
+
+ /**
+ * Recorder resume
+ */
+ resume() {
+ if (this.audioRecorder) {
+ LogUtil.info(`${TAG} audioRecorder resume`);
+ this.audioRecorder.resume();
+ }
+ }
+
+ /**
+ * Recorder stop
+ */
+ stop() {
+ if (this.audioRecorder) {
+ LogUtil.info(`${TAG} audioRecorder stop`);
+ this.audioRecorder.stop();
+ }
+ }
+}
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/src/main/ets/controller/StateController.ets b/product/phone/oh_modules/@ohos/recorder/src/main/ets/controller/StateController.ets
new file mode 100644
index 0000000000000000000000000000000000000000..bf5bc9aaaa4630c8d59c43bfb9d42c7cf26c687d
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/src/main/ets/controller/StateController.ets
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { LogUtil } from '@ohos/common';
+import { BusinessError, Callback } from '@ohos.base'
+
+const TAG = 'ControlState : ';
+
+export enum ControlState {
+ START,
+ END,
+}
+
+export class StateController {
+ private state: number = 1;
+ private stateUpdateListener?: Callback;
+
+ /**
+ * Set the status update listener
+ *
+ * @param listener
+ */
+ public setStateUpdateListener(tag: number, setStateUpdateListener: Callback): void {
+ LogUtil.info(`${TAG} setStateUpdateListener`);
+ this.stateUpdateListener = setStateUpdateListener;
+ }
+
+ /**
+ * Notification of status updates
+ */
+ private async notifyStateChanges() {
+ if (this.stateUpdateListener) {
+ this.stateUpdateListener(this.state);
+ }
+ }
+
+ /**
+ * Announce the start of recording
+ */
+ public start() {
+ LogUtil.info(`${TAG} record start.`);
+ this.state = ControlState.START;
+ this.notifyStateChanges();
+ }
+
+ /**
+ * Announce the end of recording
+ */
+ public end() {
+ LogUtil.info(`${TAG} record end.`);
+ this.state = ControlState.END;
+ this.notifyStateChanges();
+ }
+}
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/src/main/ets/model/RecordData.ets b/product/phone/oh_modules/@ohos/recorder/src/main/ets/model/RecordData.ets
new file mode 100644
index 0000000000000000000000000000000000000000..ab6a4855779936bcd3eb2a05b85087b93ac11e00
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/src/main/ets/model/RecordData.ets
@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { MediaController } from '../controller/MediaController';
+import mediaLibrary from '@ohos.multimedia.mediaLibrary';
+
+export class RecordData {
+ fileAsset: string = '';
+ title: string = '';
+ duration: number = 0;
+ date: number = 0;
+
+ constructor(fileAsset: number, date: number, title: string) {
+ if (fileAsset) {
+ if (fileAsset > 0) {
+ this.duration = fileAsset;
+ } else {
+ this.duration = 0;
+ }
+ if (date > 0) {
+ this.date = date;
+ } else {
+ this.date = 0;
+ }
+ this.title = title;
+ } else {
+ this.duration = 0;
+ this.title = '';
+ }
+ }
+}
\ No newline at end of file
diff --git a/product/phone/oh_modules/@ohos/recorder/src/main/module.json5 b/product/phone/oh_modules/@ohos/recorder/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..ed1e0395a095843abbd6047df13d59d682c9c980
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/src/main/module.json5
@@ -0,0 +1,11 @@
+{
+ "module": {
+ "name": "recorder",
+ "type": "har",
+ "deviceTypes": [
+ "default",
+ "tablet"
+ ],
+ "uiSyntax": "ets"
+ }
+}
diff --git a/product/phone/oh_modules/@ohos/recorder/src/main/resources/base/element/string.json b/product/phone/oh_modules/@ohos/recorder/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed
--- /dev/null
+++ b/product/phone/oh_modules/@ohos/recorder/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "page_show",
+ "value": "page from npm package"
+ }
+ ]
+}
diff --git a/product/phone/src/main/ets/Application/MyAbilityStage.ts b/product/phone/src/main/ets/Application/MyAbilityStage.ts
index 0a9efc1ed476ee2dfdca792a1632b37b99922670..06ad1b3deebdd690fe6a9b8dd45a97c3ef544e8a 100644
--- a/product/phone/src/main/ets/Application/MyAbilityStage.ts
+++ b/product/phone/src/main/ets/Application/MyAbilityStage.ts
@@ -13,7 +13,7 @@
* limitations under the License.
*/
-import AbilityStage from "@ohos.application.AbilityStage"
+import AbilityStage from "@ohos.app.ability.AbilityStage"
export default class MyAbilityStage extends AbilityStage {
onCreate() {
diff --git a/product/phone/src/main/ets/MainAbility/MainAbility.ts b/product/phone/src/main/ets/MainAbility/MainAbility.ts
index 67501c1826d9d010967d72a2428c02442e5d1423..a0be8b456987bbf9967475facaeaa8233b98a566 100644
--- a/product/phone/src/main/ets/MainAbility/MainAbility.ts
+++ b/product/phone/src/main/ets/MainAbility/MainAbility.ts
@@ -13,14 +13,13 @@
* limitations under the License.
*/
-import Ability from '@ohos.application.Ability'
+import Ability from '@ohos.app.ability.Ability'
import Notification from '@ohos.notification';
export default class MainAbility extends Ability {
onCreate(want, launchParam) {
console.log("[Demo] MainAbility onCreate")
globalThis.abilityWant = want;
- globalThis.abilityContext = this.context;
}
onDestroy() {
@@ -31,17 +30,6 @@ export default class MainAbility extends Ability {
onWindowStageCreate(windowStage) {
// Main window is created, set main page for this ability
console.log("[Demo] MainAbility onWindowStageCreate")
- this.context.requestPermissionsFromUser(['ohos.permission.MICROPHONE', 'ohos.permission.WRITE_MEDIA', 'ohos.permission.READ_MEDIA']).then(() => {
- Notification.requestEnableNotification().then(() => {
- windowStage.loadContent("pages/index", (err, data) => {
- if (err.code) {
- console.error('Failed to load the content. Cause:' + JSON.stringify(err));
- return;
- }
- console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data))
- });
- })
- })
}
onWindowStageDestroy() {
diff --git a/product/phone/src/main/ets/pages/RecordingPage.ets b/product/phone/src/main/ets/pages/RecordingPage.ets
index a99deb48a0189c59e7c02649a64753eaf836d043..ebe5bf0f2ab41ac2ef4ee4623bfef620ea1ab7c4 100644
--- a/product/phone/src/main/ets/pages/RecordingPage.ets
+++ b/product/phone/src/main/ets/pages/RecordingPage.ets
@@ -14,7 +14,7 @@
*/
import { ConfigData, Util } from '@ohos/common'
-import { RecordController, MediaController, RecordState } from '@ohos/recorder'
+import { RecordController, MediaController, RecordState, RecordData } from '@ohos/recorder'
import router from '@ohos.router';
import mediaLibrary from '@ohos.multimedia.mediaLibrary'
import prompt from '@ohos.prompt';
@@ -30,27 +30,10 @@ struct RecordingPage {
@State currentTime: number = 0
@State state: RecordState = RecordState.IDLE
private recordController: RecordController = new RecordController()
- @State fileAsset: mediaLibrary.FileAsset = undefined
heightList: Array = []
mIntervalId = -1
async aboutToAppear() {
- let that = this
- this.recordController.setTimeUpdateListener((currentTimeMs: number) => {
- if (Math.floor(currentTimeMs / (TIME_COUNT / 2 * 1000 * TIME_INTERVAL_S / VOICE_FREQUENCY)) - Math.floor(this.currentTime / (TIME_COUNT / 2 * 1000 * TIME_INTERVAL_S / VOICE_FREQUENCY)) == 1) {
- that.heightList.splice(0, 1)
- that.heightList.push(this.recordController.getSoundVolume())
- }
- this.currentTime = currentTimeMs
- })
- this.recordController.setStateUpdateListener((state) => {
- this.state = state
- })
- this.recordController.initAudioRecorder()
- this.fileAsset = await MediaController.createAudioFile()
- let fd = await this.fileAsset.open('Rw')
- this.recordController.startRecorder(`fd://${fd}`)
- this.initHeightList()
}
aboutToDisappear() {
@@ -95,7 +78,7 @@ struct RecordingPage {
Stack({ alignContent: Alignment.Top }) {
Column() {
Row() {
- ForEach(Array.from(Array(TIME_COUNT + 1).keys()), (item) => {
+ ForEach(Array.from(Array(TIME_COUNT + 1).keys()), (item:number) => {
Column() {
Text(Util.timeFormat(((item - (TIME_COUNT - 1) / 2) * 1000 * TIME_INTERVAL_S + Math.floor(this.currentTime / (1000 * TIME_INTERVAL_S)) * (1000 * TIME_INTERVAL_S)), false))
.textAlign(TextAlign.Center)
@@ -103,19 +86,19 @@ struct RecordingPage {
.fontSize($r("app.float.font_20"))
.opacity($r("app.float.opacity_6"))
Row() {
- ForEach(Array.from(Array(5).keys()), (scaleItem) => {
+ ForEach(Array.from(Array(5).keys()), (scaleItem:number) => {
Rect()
.width($r("app.float.wh_value_2_5"))
.fill($r("app.color.text_color"))
.height(scaleItem == 2 ? $r("app.float.wh_value_26_5") : $r("app.float.wh_value_13_5"))
.opacity(scaleItem == 2 ? $r("app.float.opacity_4") : $r("app.float.opacity_2"))
- }, scaleItem => scaleItem)
+ }, (scaleItem:number) => scaleItem+'')
}.width(ConfigData.WH_100_100)
.alignItems(VerticalAlign.Top)
.height($r("app.float.wh_value_26_5"))
.justifyContent(FlexAlign.SpaceAround)
}.width((100 / TIME_COUNT) + "%")
- }, item => item)
+ }, (item:number) => item+'')
}
.offset({
x: (-(100 / TIME_COUNT) * (this.currentTime % (TIME_INTERVAL_S * 1000) / (TIME_INTERVAL_S * 1000))) + "%"
@@ -124,13 +107,13 @@ struct RecordingPage {
Row() {
Row() {
Row() {
- ForEach(Array.from(Array(VOICE_FREQUENCY).keys()), (item) => {
+ ForEach(Array.from(Array(VOICE_FREQUENCY).keys()), (item:number) => {
Rect()
.width($r("app.float.wh_value_2_5"))
.fill($r("app.color.text_color"))
.height(this.heightList[item])
.opacity($r("app.float.opacity_2"))
- }, item => item)
+ }, (item: number) => item+'')
}.width(ConfigData.WH_100_100)
.justifyContent(FlexAlign.SpaceAround)
.offset({
@@ -201,21 +184,11 @@ struct RecordingPage {
if (this.state == RecordState.IDLE) {
let hasCall = await call.hasCall()
if (hasCall) {
- prompt.showToast({ message: $r('app.string.has_call_hint') })
} else {
this.recordController.initAudioRecorder()
- this.fileAsset = await MediaController.createAudioFile()
- let fd = await this.fileAsset.open('Rw')
- this.recordController.startRecorder(`fd://${fd}`)
}
} else {
- this.recordController.stop(() => {
- this.initHeightList()
- MediaController.saveFileDuration(this.fileAsset.title, this.currentTime)
- router.replace({
- url: "pages/index"
- })
- })
+ this.recordController.stop();
}
})
diff --git a/product/phone/src/main/ets/pages/index.ets b/product/phone/src/main/ets/pages/index.ets
index fa199ba7c4baee87b7bb8e3af2af72110c18eac2..8039e61aa667f7665f0fcfb9dea0d93fd730d0a0 100644
--- a/product/phone/src/main/ets/pages/index.ets
+++ b/product/phone/src/main/ets/pages/index.ets
@@ -28,38 +28,12 @@ struct Index {
private audioController: AudioController = new AudioController()
@State state: AudioState = AudioState.IDLE;
@State filterText: string = "";
- private deleteRecord: RecordData = undefined
- confirm: () => void = () => {
- MediaController.deleteRecord(this.deleteRecord.fileAsset.uri, () => {
- for (let i = this.recordList.length - 1;i >= 0; i--) {
- if (this.deleteRecord.fileAsset.uri == this.recordList[i].fileAsset.uri) {
- this.recordList.splice(i, 1)
- }
- }
- })
- }
- dialogController: CustomDialogController = new CustomDialogController({
- builder: DeleteRecordDialog({ deleteRecordTitle: this.deleteRecord.title, confirm: this.confirm }),
- autoCancel: true,
- alignment: DialogAlignment.Bottom,
- offset: { dy: -64, dx: 0 }
- })
+ private deleteRecord?: RecordData;
async getAudios() {
- this.recordList = await MediaController.queryAllAudios()
}
aboutToAppear() {
- this.getAudios()
- this.audioController.setTimeUpdateListener((currentTime: number) => {
- this.currentTime = currentTime
- })
- this.audioController.setStateUpdateListener((state: AudioState) => {
- if (state == AudioState.IDLE) {
- this.selectedIndex = -1
- }
- this.state = state
- })
}
build() {
@@ -109,19 +83,17 @@ struct Index {
Column() {
List() {
- ForEach([...this.recordList].reverse().map((value, index) => {
- return { i: index, data: value }
- }), (item) => {
+ ForEach([...this.recordList].reverse(), (item: RecordData, index:number) => {
ListItem() {
Column() {
Row() {
Column() {
- Text(item.data.title)
+ Text(item.title)
.fontColor($r("app.color.text_color"))
.fontSize($r("app.float.font_32"))
.width($r("app.float.wh_value_280"))
.lineHeight($r("app.float.wh_value_28"))
- Text(Util.getDateFormat(item.data.date))
+ Text(Util.getDateFormat(item.date))
.fontColor($r("app.color.text_color"))
.opacity($r("app.float.opacity_6"))
.fontSize($r("app.float.font_28"))
@@ -130,12 +102,12 @@ struct Index {
}
Row() {
- Text(Util.timeFormat(item.data.duration))
+ Text(Util.timeFormat(item.duration))
.fontColor($r("app.color.text_color"))
.opacity($r("app.float.opacity_6"))
.fontSize($r("app.float.font_28"))
.margin({ right: $r("app.float.distance_2_5") })
- Image((item.i == this.selectedIndex && this.state == AudioState.RUNNING) ? $r("app.media.ic_record_stop") : $r("app.media.ic_record_play"))
+ Image((index == this.selectedIndex && this.state == AudioState.RUNNING) ? $r("app.media.ic_record_stop") : $r("app.media.ic_record_play"))
.width($r("app.float.wh_value_32"))
.height($r("app.float.wh_value_32"))
}
@@ -145,9 +117,9 @@ struct Index {
.justifyContent(FlexAlign.SpaceBetween)
.padding({ left: $r("app.float.distance_21_5"), right: $r("app.float.distance_21_5") })
.onClick(() => {
- if (this.selectedIndex != item.i || this.state == AudioState.IDLE) {
- this.selectedIndex = item.i
- this.audioController.initAudioPlayer(item.data.fileAsset, () => {
+ if (this.selectedIndex != index || this.state == AudioState.IDLE) {
+ this.selectedIndex = index
+ this.audioController.initAudioPlayer(item.fileAsset, () => {
this.audioController.play()
})
} else if (this.state == AudioState.RUNNING) {
@@ -160,17 +132,15 @@ struct Index {
LongPressGesture()
.onAction(() => {
this.audioController.stop()
- this.deleteRecord = item.data
- this.dialogController.open()
})
)
- if (this.selectedIndex == item.i) {
+ if (this.selectedIndex == index) {
Column() {
Slider({
value: this.currentTime,
min: 0,
- max: item.data.duration,
+ max: item.duration,
style: SliderStyle.OutSet
})
.width($r("app.float.wh_value_433"))
@@ -187,7 +157,7 @@ struct Index {
.opacity($r("app.float.opacity_6"))
.fontSize($r("app.float.font_20"))
.margin({ right: $r("app.float.distance_2_5") })
- Text(Util.timeFormat(item.data.duration))
+ Text(Util.timeFormat(item.duration))
.fontColor($r("app.color.text_color"))
.opacity($r("app.float.opacity_6"))
.fontSize($r("app.float.font_20"))
@@ -200,8 +170,8 @@ struct Index {
.width(ConfigData.WH_100_100)
}
}
- }.visibility(item.data.title.indexOf(this.filterText) >= 0 ? Visibility.Visible : Visibility.None)
- }, item => item.i)
+ }.visibility(item.title.indexOf(this.filterText) >= 0 ? Visibility.Visible : Visibility.None)
+ }, (index:number) => index+'')
}.width(ConfigData.WH_100_100)
.backgroundColor($r("app.color.white"))
@@ -232,7 +202,6 @@ struct Index {
this.audioController.stop()
let hasCall = await call.hasCall()
if (hasCall) {
- prompt.showToast({ message: $r('app.string.has_call_hint') })
} else {
router.replace({
url: "pages/RecordingPage"
@@ -259,8 +228,8 @@ struct Index {
@CustomDialog
struct DeleteRecordDialog {
private controller: CustomDialogController
- private deleteRecordTitle: string
- private confirm: () => void
+ private deleteRecordTitle: string = '';
+ private confirm: () =>void = ()=>{};
build() {
Column() {
diff --git a/product/phone/src/main/module.json5 b/product/phone/src/main/module.json5
index 4bd4b498d60cc1c008a6ae0a718dcc857f6cd850..2ca2871be8f3094cc1ae99f5201a8168d89ed491 100644
--- a/product/phone/src/main/module.json5
+++ b/product/phone/src/main/module.json5
@@ -2,7 +2,7 @@
"module": {
"name": "phone",
"type": "entry",
- "srcEntrance": "./ets/Application/MyAbilityStage.ts",
+ "srcEntry": "./ets/Application/MyAbilityStage.ts",
"description": "$string:phone_desc",
"mainElement": "MainAbility",
"deviceTypes": [
@@ -15,7 +15,7 @@
"abilities": [
{
"name": "MainAbility",
- "srcEntrance": "./ets/MainAbility/MainAbility.ts",
+ "srcEntry": "./ets/MainAbility/MainAbility.ts",
"description": "$string:MainAbility_desc",
"icon": "$media:icon",
"label": "$string:MainAbility_label",
@@ -31,19 +31,25 @@
"action.system.home"
]
}
- ]
+ ],
}
],
"requestPermissions": [
- {
- "name": "ohos.permission.MICROPHONE"
- },
- {
- "name": "ohos.permission.WRITE_MEDIA"
- },
- {
- "name": "ohos.permission.READ_MEDIA"
- }
+ //{
+ //"name": "ohos.permission.MICROPHONE",
+ //"reason": This is used to record audio.,
+ //"usedScene": {
+ // "abilities":[
+ // "MainAbility"
+ // ]
+ //}
+ //},
+ //{
+ // "name": "ohos.permission.WRITE_MEDIA"
+ //},
+ //{
+ // "name": "ohos.permission.READ_MEDIA"
+ //}
]
}
}
\ No newline at end of file
diff --git a/product/tablet/oh-package-lock.json5 b/product/tablet/oh-package-lock.json5
new file mode 100644
index 0000000000000000000000000000000000000000..545f3320cc73bf737b0e6566f1f1f3224fc85abc
--- /dev/null
+++ b/product/tablet/oh-package-lock.json5
@@ -0,0 +1,25 @@
+{
+ "meta": {
+ "stableOrder": true
+ },
+ "lockfileVersion": 3,
+ "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
+ "specifiers": {
+ "@ohos/common@../../common": "@ohos/common@../../common",
+ "@ohos/recorder@../../feature/recorder": "@ohos/recorder@../../feature/recorder"
+ },
+ "packages": {
+ "@ohos/common@../../common": {
+ "name": "@ohos/common",
+ "version": "1.0.0",
+ "resolved": "../../common",
+ "registryType": "local"
+ },
+ "@ohos/recorder@../../feature/recorder": {
+ "name": "@ohos/recorder",
+ "version": "1.0.0",
+ "resolved": "../../feature/recorder",
+ "registryType": "local"
+ }
+ }
+}
\ No newline at end of file
diff --git a/product/tablet/oh-package.json5 b/product/tablet/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..2ba09c95369c7b92b119169a7c35d7d369e182b6
--- /dev/null
+++ b/product/tablet/oh-package.json5
@@ -0,0 +1,12 @@
+{
+ "license": "ISC",
+ "devDependencies": {},
+ "name": "tablet",
+ "description": "example description",
+ "version": "1.0.0",
+ "dynamicDependencies": {},
+ "dependencies": {
+ "@ohos/recorder": "file:../../feature/recorder",
+ "@ohos/common": "file:../../common"
+ }
+}
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/common/.gitignore b/product/tablet/oh_modules/@ohos/common/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4f9a973815d0b5e49bc8547681a6b4bc7a178d12
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/.gitignore
@@ -0,0 +1,3 @@
+/node_modules
+/.preview
+/build
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/common/BuildProfile.ets b/product/tablet/oh_modules/@ohos/common/BuildProfile.ets
new file mode 100644
index 0000000000000000000000000000000000000000..3a501e5ddee8ea6d28961648fc7dd314a5304bd4
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/BuildProfile.ets
@@ -0,0 +1,17 @@
+/**
+ * Use these variables when you tailor your ArkTS code. They must be of the const type.
+ */
+export const HAR_VERSION = '1.0.0';
+export const BUILD_MODE_NAME = 'debug';
+export const DEBUG = true;
+export const TARGET_NAME = 'default';
+
+/**
+ * BuildProfile Class is used only for compatibility purposes.
+ */
+export default class BuildProfile {
+ static readonly HAR_VERSION = HAR_VERSION;
+ static readonly BUILD_MODE_NAME = BUILD_MODE_NAME;
+ static readonly DEBUG = DEBUG;
+ static readonly TARGET_NAME = TARGET_NAME;
+}
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/common/build-profile.json5 b/product/tablet/oh_modules/@ohos/common/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..7374b5c13faa1f45347034d15c09cbc09a8ab154
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/build-profile.json5
@@ -0,0 +1,17 @@
+{
+ "apiType": "stageMode",
+ "buildOption": {
+ },
+ "buildOptionSet": [
+ {
+ "name": "release",
+ "arkOptions": {
+ "obfuscation": {
+ "ruleOptions": {
+ "enable": false,
+ }
+ }
+ }
+ },
+ ]
+}
diff --git a/product/tablet/oh_modules/@ohos/common/hvigorfile.js b/product/tablet/oh_modules/@ohos/common/hvigorfile.js
new file mode 100644
index 0000000000000000000000000000000000000000..42ed4b4a54a873e2b53441556aae93fab24b794f
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/hvigorfile.js
@@ -0,0 +1,3 @@
+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
+module.exports = require('@ohos/hvigor-ohos-plugin').harTasks
+
diff --git a/product/tablet/oh_modules/@ohos/common/index.ets b/product/tablet/oh_modules/@ohos/common/index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..af9c605b34eec7395760f18018aea72ecbd1e703
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/index.ets
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { default as ConfigData } from './src/main/ets/utils/ConfigData'
+
+export { default as Util } from './src/main/ets/utils/Util'
+
+export { default as LogUtil } from './src/main/ets/utils/LogUtil'
diff --git a/product/tablet/oh_modules/@ohos/common/oh-package.json5 b/product/tablet/oh_modules/@ohos/common/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..3159c134e8893daf7afdf1dc73ed683c7ee24fc2
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/oh-package.json5
@@ -0,0 +1,12 @@
+{
+ "license": "ISC",
+ "types": "",
+ "devDependencies": {},
+ "name": "@ohos/common",
+ "description": "a npm package which contains arkUI2.0 page",
+ "ohos": {
+ "org": ""
+ },
+ "main": "index.ets",
+ "version": "1.0.0",
+}
diff --git a/product/tablet/oh_modules/@ohos/common/package.json b/product/tablet/oh_modules/@ohos/common/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..dfbf6f7a0611aa4c4fa5f81337f132a4f4a9a694
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/package.json
@@ -0,0 +1,16 @@
+{
+ "license": "ISC",
+ "types": "",
+ "devDependencies": {},
+ "name": "@ohos/common",
+ "description": "a npm package which contains arkUI2.0 page",
+ "ohos": {
+ "org": ""
+ },
+ "main": "src/main/ets/components/MainPage/MainPage.ets",
+ "repository": {},
+ "version": "1.0.0",
+ "dependencies": {
+ "@ohos/hap": "^3.0.0"
+ }
+}
diff --git a/product/tablet/oh_modules/@ohos/common/src/main/ets/utils/ConfigData.ets b/product/tablet/oh_modules/@ohos/common/src/main/ets/utils/ConfigData.ets
new file mode 100644
index 0000000000000000000000000000000000000000..728136a483d65992eec74b7fd766c0e7792b66cb
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/src/main/ets/utils/ConfigData.ets
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export class ConfigData {
+ WH_100_100 = '100%';
+ WH_50_100 = '50%';
+ WH_40_100 = '40%';
+ WH_20_100 = '20%';
+}
+
+let configData = new ConfigData();
+
+export default configData as ConfigData;
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/common/src/main/ets/utils/LogUtil.ts b/product/tablet/oh_modules/@ohos/common/src/main/ets/utils/LogUtil.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bbead9dd9befd61c6caee01842404061533ef8aa
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/src/main/ets/utils/LogUtil.ts
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import HiLog from "@ohos.hilog";
+
+const DOMAIN = 0x0500;
+const TAG = "[Recorder]";
+
+/**
+ * log package tool class
+ */
+export default class LogUtil {
+ static debug(msg): void {
+ HiLog.debug(DOMAIN, TAG, msg);
+ }
+
+ static log(msg): void {
+ HiLog.info(DOMAIN, TAG, msg);
+ }
+
+ static info(msg): void {
+ HiLog.info(DOMAIN, TAG, msg);
+ }
+
+ static warn(msg): void {
+ HiLog.warn(DOMAIN, TAG, msg);
+ }
+
+ static error(msg): void {
+ HiLog.error(DOMAIN, TAG, msg);
+ }
+}
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/common/src/main/ets/utils/Util.ets b/product/tablet/oh_modules/@ohos/common/src/main/ets/utils/Util.ets
new file mode 100644
index 0000000000000000000000000000000000000000..d7ff0707252d2bb0d89e37c144e7fdfab82fb52e
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/src/main/ets/utils/Util.ets
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default class Util {
+
+ /**
+ * Time format is converted to seconds
+ *
+ * @param timestamp
+ * @param hasHour
+ */
+ static timeFormat(timestamp: number, hasHour: boolean = true): string {
+ if (timestamp < 0) {
+ return "";
+ }
+ let timeStr = "";
+ let hour = Math.floor(timestamp % (24 * 60 * 60 * 1000) / (60 * 60 * 1000));
+ if (hasHour || hour > 0) {
+ timeStr += Util.addZero(hour) + ":";
+ }
+ let min = Math.floor(timestamp % (60 * 60 * 1000) / (60 * 1000));
+ timeStr += Util.addZero(min) + ":";
+ let sec = Math.floor(timestamp % (60 * 1000) / 1000);
+ timeStr += Util.addZero(sec);
+ return timeStr;
+ }
+
+ /**
+ * Time format is converted to milliseconds
+ *
+ * @param timestamp
+ */
+ static timeFormatMs(timestamp: number): string {
+ if (timestamp <= 0) {
+ return "00:00.00";
+ }
+ let timeStr = "";
+ let hour = Math.floor(timestamp % (24 * 60 * 60 * 1000) / (60 * 60 * 1000));
+ if (hour > 0) {
+ timeStr += Util.addZero(hour) + ":";
+ }
+ let min = Math.floor(timestamp % (60 * 60 * 1000) / (60 * 1000));
+ timeStr += Util.addZero(min) + ":";
+ let sec = Math.floor(timestamp % (60 * 1000) / 1000);
+ timeStr += Util.addZero(sec);
+ if (hour < 1) {
+ let mSec = Math.floor(timestamp % 1000 / 10);
+ timeStr += "." + Util.addZero(mSec);
+ }
+ return timeStr;
+ }
+
+ /**
+ * Gets the date at the specified time
+ *
+ * @param date
+ */
+ static getDateFormat(date: number): string {
+ let nowDate = new Date(date);
+ return nowDate.getFullYear() + "/" + Util.addZero(nowDate.getMonth() + 1) + "/" + Util.addZero(nowDate.getDate());
+ }
+
+ /**
+ * Gets the hour, minute and second of the specified time
+ *
+ * @param date
+ */
+ static getTimeFormat(date: number): string {
+ let nowDate = new Date(date);
+ return Util.addZero(nowDate.getHours()) + ":" + Util.addZero(nowDate.getMinutes()) + ":" + Util.addZero(nowDate.getSeconds());
+ }
+
+ /**
+ * Gets the current time date
+ */
+ static getDate(): string {
+ let nowDate = new Date();
+ return nowDate.getFullYear() + Util.addZero(nowDate.getMonth() + 1) + Util.addZero(nowDate.getDate());
+ }
+
+ /**
+ * Gets the hour, minute and second of the current time
+ */
+ static getTime(): string {
+ let nowDate = new Date();
+ return Util.addZero(nowDate.getHours()) + Util.addZero(nowDate.getMinutes()) + Util.addZero(nowDate.getSeconds());
+ }
+
+ /**
+ * If the number is less than 10, add "0".
+ *
+ * @param num
+ */
+ static addZero(num: number): string{
+ return (num < 10 ? "0" + num : num).toString();
+ }
+}
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/common/src/main/module.json5 b/product/tablet/oh_modules/@ohos/common/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..56a91a87ba3ea303b57e4b8e5f405e9d6d2a800a
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/src/main/module.json5
@@ -0,0 +1,11 @@
+{
+ "module": {
+ "name": "common",
+ "type": "har",
+ "deviceTypes": [
+ "default",
+ "tablet"
+ ],
+ "uiSyntax": "ets"
+ }
+}
diff --git a/product/tablet/oh_modules/@ohos/common/src/main/resources/base/element/color.json b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..ffe7272ac3029e44fd8fe56844ac7a59808be8a2
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/element/color.json
@@ -0,0 +1,32 @@
+{
+ "color": [
+ {
+ "name": "white",
+ "value": "#FFFFFF"
+ },
+ {
+ "name": "background_color",
+ "value": "#F1F3F5"
+ },
+ {
+ "name": "shadow_color",
+ "value": "#11000000"
+ },
+ {
+ "name": "pointer_color",
+ "value": "#007DFF"
+ },
+ {
+ "name": "warn_color",
+ "value": "#FF595A"
+ },
+ {
+ "name": "hint_color",
+ "value": "#007DFF"
+ },
+ {
+ "name": "text_color",
+ "value": "#182431"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/common/src/main/resources/base/element/string.json b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..2375b2de43748384262b8e07fa36405169d878c8
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/element/string.json
@@ -0,0 +1,56 @@
+{
+ "string": [
+ {
+ "name": "page_show",
+ "value": "page from npm package"
+ },
+ {
+ "name": "title",
+ "value": "录音机"
+ },
+ {
+ "name": "search_recording_files",
+ "value": "搜索录音文件"
+ },
+ {
+ "name": "mark",
+ "value": "标记"
+ },
+ {
+ "name": "pause",
+ "value": "暂停"
+ },
+ {
+ "name": "continue_record",
+ "value": "继续"
+ },
+ {
+ "name": "predict_hint",
+ "value": "预计还能录制10小时以上"
+ },
+ {
+ "name": "delete_hint",
+ "value": "是否删除此条录音?"
+ },
+ {
+ "name": "cancel",
+ "value": "取消"
+ },
+ {
+ "name": "delete",
+ "value": "删除"
+ },
+ {
+ "name": "has_call_hint",
+ "value": "通话状态无法录音"
+ },
+ {
+ "name": "recording_hint",
+ "value": "录音机正在录音"
+ },
+ {
+ "name": "suspend_record_hint",
+ "value": "录音机暂停录音"
+ }
+ ]
+}
diff --git a/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/bg_record.png b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/bg_record.png
new file mode 100644
index 0000000000000000000000000000000000000000..41c12ccb5bb90cd9c05508690ca0b88f33e96008
Binary files /dev/null and b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/bg_record.png differ
diff --git a/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_back.svg b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_back.svg
new file mode 100644
index 0000000000000000000000000000000000000000..6f7f039226e90d3ef91b0e83c4ad29236858e868
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_back.svg
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_add.svg b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_add.svg
new file mode 100644
index 0000000000000000000000000000000000000000..3ec94e4b1e5f198844f5136dc14c9ff00ab95887
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_add.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_enhance.svg b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_enhance.svg
new file mode 100644
index 0000000000000000000000000000000000000000..14a0ba5bbea05082e4659a124dc89b79f523509b
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_enhance.svg
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_mark.svg b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_mark.svg
new file mode 100644
index 0000000000000000000000000000000000000000..330eda737a418114cc3389b4c14cbcada67ec5e9
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_mark.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_play.svg b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_play.svg
new file mode 100644
index 0000000000000000000000000000000000000000..4a6c56994bd7736e81307833789775d51b71cf6c
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_play.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_record.svg b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_record.svg
new file mode 100644
index 0000000000000000000000000000000000000000..c8f7906490d4e4ae103cf1d35fd3e5c4c55f27f0
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_record.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_stop.svg b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_stop.svg
new file mode 100644
index 0000000000000000000000000000000000000000..02964494e7ad6466ce03c368befe5a7e3c1ed01b
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_stop.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_suspend.svg b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_suspend.svg
new file mode 100644
index 0000000000000000000000000000000000000000..bf6f0ea2eabe25b77ef0bed04d52cb1e6ac6bb0b
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_suspend.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_play.svg b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_play.svg
new file mode 100644
index 0000000000000000000000000000000000000000..34c0e947768885c982a4031b2df92c1fe7b014ab
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_play.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_search.svg b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_search.svg
new file mode 100644
index 0000000000000000000000000000000000000000..1b2a8aa35dc2c2ea6b47fad1fdfe319947701b43
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_search.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_stop.svg b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_stop.svg
new file mode 100644
index 0000000000000000000000000000000000000000..2b7ceaa1d1b8a10b1b18f0a1515477874df4b357
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_stop.svg
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/public_more.svg b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/public_more.svg
new file mode 100644
index 0000000000000000000000000000000000000000..400c3ef1abe1ebe1b0637b20c1c4b9711812b41e
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/common/src/main/resources/base/media/public_more.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/.gitignore b/product/tablet/oh_modules/@ohos/recorder/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4f9a973815d0b5e49bc8547681a6b4bc7a178d12
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/.gitignore
@@ -0,0 +1,3 @@
+/node_modules
+/.preview
+/build
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/BuildProfile.ets b/product/tablet/oh_modules/@ohos/recorder/BuildProfile.ets
new file mode 100644
index 0000000000000000000000000000000000000000..3a501e5ddee8ea6d28961648fc7dd314a5304bd4
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/BuildProfile.ets
@@ -0,0 +1,17 @@
+/**
+ * Use these variables when you tailor your ArkTS code. They must be of the const type.
+ */
+export const HAR_VERSION = '1.0.0';
+export const BUILD_MODE_NAME = 'debug';
+export const DEBUG = true;
+export const TARGET_NAME = 'default';
+
+/**
+ * BuildProfile Class is used only for compatibility purposes.
+ */
+export default class BuildProfile {
+ static readonly HAR_VERSION = HAR_VERSION;
+ static readonly BUILD_MODE_NAME = BUILD_MODE_NAME;
+ static readonly DEBUG = DEBUG;
+ static readonly TARGET_NAME = TARGET_NAME;
+}
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/build-profile.json5 b/product/tablet/oh_modules/@ohos/recorder/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..35dff6d53cb3a241f8de4fb68bd01d38ade0f108
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/build-profile.json5
@@ -0,0 +1,5 @@
+{
+ "apiType": "stageMode",
+ "buildOption": {
+ }
+}
diff --git a/product/tablet/oh_modules/@ohos/recorder/hvigorfile.js b/product/tablet/oh_modules/@ohos/recorder/hvigorfile.js
new file mode 100644
index 0000000000000000000000000000000000000000..42ed4b4a54a873e2b53441556aae93fab24b794f
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/hvigorfile.js
@@ -0,0 +1,3 @@
+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
+module.exports = require('@ohos/hvigor-ohos-plugin').harTasks
+
diff --git a/product/tablet/oh_modules/@ohos/recorder/index.ets b/product/tablet/oh_modules/@ohos/recorder/index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..98c643021853a081786f585ce73e679d2f0a3df7
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/index.ets
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { RecordController, RecordState } from './src/main/ets/controller/RecordController'
+
+export { default as MediaController } from './src/main/ets/controller/MediaController'
+
+export { AudioController, AudioState } from './src/main/ets/controller/AudioController'
+
+export { StateController, ControlState } from './src/main/ets/controller/StateController'
+
+export { RecordData } from './src/main/ets/model/RecordData'
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh-package-lock.json5 b/product/tablet/oh_modules/@ohos/recorder/oh-package-lock.json5
new file mode 100644
index 0000000000000000000000000000000000000000..71fb2aa27ea03ee139d0c1365fbfd5ab52c7931d
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh-package-lock.json5
@@ -0,0 +1,18 @@
+{
+ "meta": {
+ "stableOrder": true
+ },
+ "lockfileVersion": 3,
+ "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
+ "specifiers": {
+ "@ohos/common@../../common": "@ohos/common@../../common"
+ },
+ "packages": {
+ "@ohos/common@../../common": {
+ "name": "@ohos/common",
+ "version": "1.0.0",
+ "resolved": "../../common",
+ "registryType": "local"
+ }
+ }
+}
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh-package.json5 b/product/tablet/oh_modules/@ohos/recorder/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..c395a2849c8e98e829d405d584bcb87dc6cfa72b
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh-package.json5
@@ -0,0 +1,13 @@
+{
+ "license": "ISC",
+ "types": "",
+ "devDependencies": {
+ "@ohos/common": "file:../../common"
+ },
+ "name": "@ohos/recorder",
+ "description": "a npm package which contains arkUI2.0 page",
+ "main": "index.ets",
+ "version": "1.0.0",
+ "dynamicDependencies": {},
+ "dependencies": {}
+}
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/.gitignore b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4f9a973815d0b5e49bc8547681a6b4bc7a178d12
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/.gitignore
@@ -0,0 +1,3 @@
+/node_modules
+/.preview
+/build
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/BuildProfile.ets b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/BuildProfile.ets
new file mode 100644
index 0000000000000000000000000000000000000000..3a501e5ddee8ea6d28961648fc7dd314a5304bd4
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/BuildProfile.ets
@@ -0,0 +1,17 @@
+/**
+ * Use these variables when you tailor your ArkTS code. They must be of the const type.
+ */
+export const HAR_VERSION = '1.0.0';
+export const BUILD_MODE_NAME = 'debug';
+export const DEBUG = true;
+export const TARGET_NAME = 'default';
+
+/**
+ * BuildProfile Class is used only for compatibility purposes.
+ */
+export default class BuildProfile {
+ static readonly HAR_VERSION = HAR_VERSION;
+ static readonly BUILD_MODE_NAME = BUILD_MODE_NAME;
+ static readonly DEBUG = DEBUG;
+ static readonly TARGET_NAME = TARGET_NAME;
+}
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/build-profile.json5 b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..7374b5c13faa1f45347034d15c09cbc09a8ab154
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/build-profile.json5
@@ -0,0 +1,17 @@
+{
+ "apiType": "stageMode",
+ "buildOption": {
+ },
+ "buildOptionSet": [
+ {
+ "name": "release",
+ "arkOptions": {
+ "obfuscation": {
+ "ruleOptions": {
+ "enable": false,
+ }
+ }
+ }
+ },
+ ]
+}
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/hvigorfile.js b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/hvigorfile.js
new file mode 100644
index 0000000000000000000000000000000000000000..42ed4b4a54a873e2b53441556aae93fab24b794f
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/hvigorfile.js
@@ -0,0 +1,3 @@
+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
+module.exports = require('@ohos/hvigor-ohos-plugin').harTasks
+
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/index.ets b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..af9c605b34eec7395760f18018aea72ecbd1e703
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/index.ets
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { default as ConfigData } from './src/main/ets/utils/ConfigData'
+
+export { default as Util } from './src/main/ets/utils/Util'
+
+export { default as LogUtil } from './src/main/ets/utils/LogUtil'
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/oh-package.json5 b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..3159c134e8893daf7afdf1dc73ed683c7ee24fc2
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/oh-package.json5
@@ -0,0 +1,12 @@
+{
+ "license": "ISC",
+ "types": "",
+ "devDependencies": {},
+ "name": "@ohos/common",
+ "description": "a npm package which contains arkUI2.0 page",
+ "ohos": {
+ "org": ""
+ },
+ "main": "index.ets",
+ "version": "1.0.0",
+}
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/package.json b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..dfbf6f7a0611aa4c4fa5f81337f132a4f4a9a694
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/package.json
@@ -0,0 +1,16 @@
+{
+ "license": "ISC",
+ "types": "",
+ "devDependencies": {},
+ "name": "@ohos/common",
+ "description": "a npm package which contains arkUI2.0 page",
+ "ohos": {
+ "org": ""
+ },
+ "main": "src/main/ets/components/MainPage/MainPage.ets",
+ "repository": {},
+ "version": "1.0.0",
+ "dependencies": {
+ "@ohos/hap": "^3.0.0"
+ }
+}
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/ets/utils/ConfigData.ets b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/ets/utils/ConfigData.ets
new file mode 100644
index 0000000000000000000000000000000000000000..728136a483d65992eec74b7fd766c0e7792b66cb
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/ets/utils/ConfigData.ets
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export class ConfigData {
+ WH_100_100 = '100%';
+ WH_50_100 = '50%';
+ WH_40_100 = '40%';
+ WH_20_100 = '20%';
+}
+
+let configData = new ConfigData();
+
+export default configData as ConfigData;
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/ets/utils/LogUtil.ts b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/ets/utils/LogUtil.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bbead9dd9befd61c6caee01842404061533ef8aa
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/ets/utils/LogUtil.ts
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import HiLog from "@ohos.hilog";
+
+const DOMAIN = 0x0500;
+const TAG = "[Recorder]";
+
+/**
+ * log package tool class
+ */
+export default class LogUtil {
+ static debug(msg): void {
+ HiLog.debug(DOMAIN, TAG, msg);
+ }
+
+ static log(msg): void {
+ HiLog.info(DOMAIN, TAG, msg);
+ }
+
+ static info(msg): void {
+ HiLog.info(DOMAIN, TAG, msg);
+ }
+
+ static warn(msg): void {
+ HiLog.warn(DOMAIN, TAG, msg);
+ }
+
+ static error(msg): void {
+ HiLog.error(DOMAIN, TAG, msg);
+ }
+}
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/ets/utils/Util.ets b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/ets/utils/Util.ets
new file mode 100644
index 0000000000000000000000000000000000000000..d7ff0707252d2bb0d89e37c144e7fdfab82fb52e
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/ets/utils/Util.ets
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export default class Util {
+
+ /**
+ * Time format is converted to seconds
+ *
+ * @param timestamp
+ * @param hasHour
+ */
+ static timeFormat(timestamp: number, hasHour: boolean = true): string {
+ if (timestamp < 0) {
+ return "";
+ }
+ let timeStr = "";
+ let hour = Math.floor(timestamp % (24 * 60 * 60 * 1000) / (60 * 60 * 1000));
+ if (hasHour || hour > 0) {
+ timeStr += Util.addZero(hour) + ":";
+ }
+ let min = Math.floor(timestamp % (60 * 60 * 1000) / (60 * 1000));
+ timeStr += Util.addZero(min) + ":";
+ let sec = Math.floor(timestamp % (60 * 1000) / 1000);
+ timeStr += Util.addZero(sec);
+ return timeStr;
+ }
+
+ /**
+ * Time format is converted to milliseconds
+ *
+ * @param timestamp
+ */
+ static timeFormatMs(timestamp: number): string {
+ if (timestamp <= 0) {
+ return "00:00.00";
+ }
+ let timeStr = "";
+ let hour = Math.floor(timestamp % (24 * 60 * 60 * 1000) / (60 * 60 * 1000));
+ if (hour > 0) {
+ timeStr += Util.addZero(hour) + ":";
+ }
+ let min = Math.floor(timestamp % (60 * 60 * 1000) / (60 * 1000));
+ timeStr += Util.addZero(min) + ":";
+ let sec = Math.floor(timestamp % (60 * 1000) / 1000);
+ timeStr += Util.addZero(sec);
+ if (hour < 1) {
+ let mSec = Math.floor(timestamp % 1000 / 10);
+ timeStr += "." + Util.addZero(mSec);
+ }
+ return timeStr;
+ }
+
+ /**
+ * Gets the date at the specified time
+ *
+ * @param date
+ */
+ static getDateFormat(date: number): string {
+ let nowDate = new Date(date);
+ return nowDate.getFullYear() + "/" + Util.addZero(nowDate.getMonth() + 1) + "/" + Util.addZero(nowDate.getDate());
+ }
+
+ /**
+ * Gets the hour, minute and second of the specified time
+ *
+ * @param date
+ */
+ static getTimeFormat(date: number): string {
+ let nowDate = new Date(date);
+ return Util.addZero(nowDate.getHours()) + ":" + Util.addZero(nowDate.getMinutes()) + ":" + Util.addZero(nowDate.getSeconds());
+ }
+
+ /**
+ * Gets the current time date
+ */
+ static getDate(): string {
+ let nowDate = new Date();
+ return nowDate.getFullYear() + Util.addZero(nowDate.getMonth() + 1) + Util.addZero(nowDate.getDate());
+ }
+
+ /**
+ * Gets the hour, minute and second of the current time
+ */
+ static getTime(): string {
+ let nowDate = new Date();
+ return Util.addZero(nowDate.getHours()) + Util.addZero(nowDate.getMinutes()) + Util.addZero(nowDate.getSeconds());
+ }
+
+ /**
+ * If the number is less than 10, add "0".
+ *
+ * @param num
+ */
+ static addZero(num: number): string{
+ return (num < 10 ? "0" + num : num).toString();
+ }
+}
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/module.json5 b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..56a91a87ba3ea303b57e4b8e5f405e9d6d2a800a
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/module.json5
@@ -0,0 +1,11 @@
+{
+ "module": {
+ "name": "common",
+ "type": "har",
+ "deviceTypes": [
+ "default",
+ "tablet"
+ ],
+ "uiSyntax": "ets"
+ }
+}
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/element/color.json b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..ffe7272ac3029e44fd8fe56844ac7a59808be8a2
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/element/color.json
@@ -0,0 +1,32 @@
+{
+ "color": [
+ {
+ "name": "white",
+ "value": "#FFFFFF"
+ },
+ {
+ "name": "background_color",
+ "value": "#F1F3F5"
+ },
+ {
+ "name": "shadow_color",
+ "value": "#11000000"
+ },
+ {
+ "name": "pointer_color",
+ "value": "#007DFF"
+ },
+ {
+ "name": "warn_color",
+ "value": "#FF595A"
+ },
+ {
+ "name": "hint_color",
+ "value": "#007DFF"
+ },
+ {
+ "name": "text_color",
+ "value": "#182431"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/element/string.json b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..2375b2de43748384262b8e07fa36405169d878c8
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/element/string.json
@@ -0,0 +1,56 @@
+{
+ "string": [
+ {
+ "name": "page_show",
+ "value": "page from npm package"
+ },
+ {
+ "name": "title",
+ "value": "录音机"
+ },
+ {
+ "name": "search_recording_files",
+ "value": "搜索录音文件"
+ },
+ {
+ "name": "mark",
+ "value": "标记"
+ },
+ {
+ "name": "pause",
+ "value": "暂停"
+ },
+ {
+ "name": "continue_record",
+ "value": "继续"
+ },
+ {
+ "name": "predict_hint",
+ "value": "预计还能录制10小时以上"
+ },
+ {
+ "name": "delete_hint",
+ "value": "是否删除此条录音?"
+ },
+ {
+ "name": "cancel",
+ "value": "取消"
+ },
+ {
+ "name": "delete",
+ "value": "删除"
+ },
+ {
+ "name": "has_call_hint",
+ "value": "通话状态无法录音"
+ },
+ {
+ "name": "recording_hint",
+ "value": "录音机正在录音"
+ },
+ {
+ "name": "suspend_record_hint",
+ "value": "录音机暂停录音"
+ }
+ ]
+}
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/bg_record.png b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/bg_record.png
new file mode 100644
index 0000000000000000000000000000000000000000..41c12ccb5bb90cd9c05508690ca0b88f33e96008
Binary files /dev/null and b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/bg_record.png differ
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_back.svg b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_back.svg
new file mode 100644
index 0000000000000000000000000000000000000000..6f7f039226e90d3ef91b0e83c4ad29236858e868
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_back.svg
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_add.svg b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_add.svg
new file mode 100644
index 0000000000000000000000000000000000000000..3ec94e4b1e5f198844f5136dc14c9ff00ab95887
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_add.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_enhance.svg b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_enhance.svg
new file mode 100644
index 0000000000000000000000000000000000000000..14a0ba5bbea05082e4659a124dc89b79f523509b
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_enhance.svg
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_mark.svg b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_mark.svg
new file mode 100644
index 0000000000000000000000000000000000000000..330eda737a418114cc3389b4c14cbcada67ec5e9
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_mark.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_play.svg b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_play.svg
new file mode 100644
index 0000000000000000000000000000000000000000..4a6c56994bd7736e81307833789775d51b71cf6c
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_play.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_record.svg b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_record.svg
new file mode 100644
index 0000000000000000000000000000000000000000..c8f7906490d4e4ae103cf1d35fd3e5c4c55f27f0
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_record.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_stop.svg b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_stop.svg
new file mode 100644
index 0000000000000000000000000000000000000000..02964494e7ad6466ce03c368befe5a7e3c1ed01b
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_stop.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_suspend.svg b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_suspend.svg
new file mode 100644
index 0000000000000000000000000000000000000000..bf6f0ea2eabe25b77ef0bed04d52cb1e6ac6bb0b
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_clock_suspend.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_play.svg b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_play.svg
new file mode 100644
index 0000000000000000000000000000000000000000..34c0e947768885c982a4031b2df92c1fe7b014ab
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_play.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_search.svg b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_search.svg
new file mode 100644
index 0000000000000000000000000000000000000000..1b2a8aa35dc2c2ea6b47fad1fdfe319947701b43
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_search.svg
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_stop.svg b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_stop.svg
new file mode 100644
index 0000000000000000000000000000000000000000..2b7ceaa1d1b8a10b1b18f0a1515477874df4b357
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/ic_record_stop.svg
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/public_more.svg b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/public_more.svg
new file mode 100644
index 0000000000000000000000000000000000000000..400c3ef1abe1ebe1b0637b20c1c4b9711812b41e
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/oh_modules/@ohos/common/src/main/resources/base/media/public_more.svg
@@ -0,0 +1,13 @@
+
+
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/package.json b/product/tablet/oh_modules/@ohos/recorder/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..83c74cf381e47f923fd3171be67a35594e7224e6
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/package.json
@@ -0,0 +1,16 @@
+{
+ "license": "ISC",
+ "types": "",
+ "devDependencies": {},
+ "name": "@ohos/recorder",
+ "description": "a npm package which contains arkUI2.0 page",
+ "ohos": {
+ "org": ""
+ },
+ "main": "src/main/ets/components/MainPage/MainPage.ets",
+ "repository": {},
+ "version": "1.0.0",
+ "dependencies": {
+ "@ohos/common": "file:../../common"
+ }
+}
diff --git a/product/tablet/oh_modules/@ohos/recorder/src/main/ets/controller/AudioController.ets b/product/tablet/oh_modules/@ohos/recorder/src/main/ets/controller/AudioController.ets
new file mode 100644
index 0000000000000000000000000000000000000000..2b1cae60bf5f1691912519eeb7df29fd37263f18
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/src/main/ets/controller/AudioController.ets
@@ -0,0 +1,202 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import mediaLibrary from '@ohos.multimedia.mediaLibrary';
+import media from '@ohos.multimedia.media';
+import { LogUtil } from '@ohos/common';
+import { BusinessError, Callback } from '@ohos.base'
+
+export enum AudioState {
+ /**
+ * The initial state
+ */
+ IDLE,
+ /**
+ * Continuously update time starting from IDLE state or PAUSED state
+ */
+ RUNNING,
+ /**
+ * Click Pause from the RUNNING state
+ */
+ PAUSED,
+}
+
+const NOTIFY_INTERVAL_MS = 50;
+const TAG = "AudioController : ";
+
+export class AudioController {
+ private audioPlayer?: media.AVPlayer;
+ private state: string = 'idle';
+ private playFile: string = '';
+ private dataLoad: boolean = false;
+ private currentTimeMs: number = 0;
+ private intervalId: number = -1;
+ private timeUpdateListener?: Callback;
+ private stateUpdateListener?: Callback;
+
+ /**
+ * Set the time update listener
+ *
+ * @param listener
+ */
+ public setTimeUpdateListener(tag: string, timeUpdateListener: Callback): void {
+ LogUtil.info(`${TAG} setTimeUpdateListener`);
+ this.timeUpdateListener = timeUpdateListener;
+ }
+
+ /**
+ * Set the status update listener
+ *
+ * @param listener
+ */
+ public setStateUpdateListener(tag: string, setStateUpdateListener: Callback): void {
+ LogUtil.info(`${TAG} setStateUpdateListener`);
+ this.stateUpdateListener = setStateUpdateListener;
+ }
+
+ /**
+ * Notification time update
+ */
+ private notifyTimeChanges() {
+ if (this.timeUpdateListener) {
+ this.timeUpdateListener(this.currentTimeMs);
+ }
+ }
+
+ /**
+ * Notification of status updates
+ */
+ private async notifyStateChanges() {
+ if (this.stateUpdateListener) {
+ LogUtil.info(`${TAG} state update ${this.state}`);
+ this.stateUpdateListener(this.state);
+ }
+ }
+
+ /**
+ * Initialize the audio player
+ *
+ * @param playSrc
+ * @param callback
+ */
+ async initAudioPlayer(playSrc: string, callback: () => void) {
+ LogUtil.info(`${TAG} initAudioPlayer`);
+ this.playFile = playSrc;
+ this.dataLoad = false;
+ this.release();
+ LogUtil.info(`${TAG} createAudioPlayer`);
+ if (!this.audioPlayer) {
+ return;
+ }
+ try {
+ this.audioPlayer = await media.createAVPlayer();
+ } catch (e) {
+ }
+ this.audioPlayer?.on('stateChange', this.stateChangeListener)
+ }
+
+ private stateChangeListener = async (state: string, reason: media.StateChangeReason) => {
+ if (!this.audioPlayer) {
+ return;
+ }
+ this.state = state;
+ switch (state) {
+ case 'idle' :
+ break;
+ case 'initialized':
+ break;
+ case 'playing':
+ break;
+ case 'prepared':
+ break;
+ case 'paused':
+ break;
+ case 'completed':
+ break;
+ case 'stopped':
+ case 'released':
+ break;
+ }
+ }
+ /**
+ * audioPlayer play
+ */
+ play() {
+ try {
+ if (this.audioPlayer) {
+ this.audioPlayer.play();
+ }
+ } catch (e) {
+ }
+ }
+
+ /**
+ * audioPlayer seek time
+ *
+ * @param timeMs
+ */
+ seek(timeMs: number) {
+ if (this.audioPlayer) {
+ LogUtil.info(`${TAG} audioPlayer time to jump. time:` + timeMs);
+ this.audioPlayer.seek(timeMs);
+ }
+ }
+
+ /**
+ * audioPlayer pause
+ */
+ pause() {
+ if (this.audioPlayer) {
+ LogUtil.info(`${TAG} audioPlayer pause`);
+ this.audioPlayer.pause();
+ }
+ }
+
+ /**
+ * audioPlayer stop
+ */
+ stop() {
+ if ((this.audioPlayer) && this.state != 'idle') {
+ LogUtil.info(`${TAG} audioPlayer stop`);
+ this.state = 'idle';
+ this.audioPlayer.release();
+ this.intervalId = -1;
+ }
+ }
+
+ /**
+ * audioPlayer continue play
+ */
+ continuePlay() {
+ if (this.audioPlayer) {
+ LogUtil.info(`${TAG} audioPlayer continue play`);
+ this.audioPlayer.play();
+ }
+ }
+
+ /**
+ * audioPlayer release
+ */
+ release() {
+ if (this.audioPlayer) {
+ this.currentTimeMs = 0;
+ this.notifyTimeChanges();
+ LogUtil.info(`${TAG} audioPlayer release`);
+ this.audioPlayer.release();
+ this.audioPlayer = undefined;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/src/main/ets/controller/MediaController.ets b/product/tablet/oh_modules/@ohos/recorder/src/main/ets/controller/MediaController.ets
new file mode 100644
index 0000000000000000000000000000000000000000..db8262d36fd8eae29ec262333d9b58a25f0b9b12
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/src/main/ets/controller/MediaController.ets
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import mediaLibrary from '@ohos.multimedia.mediaLibrary';
+import { Util } from '@ohos/common';
+import { RecordData } from '../model/RecordData';
+import data_preferences from '@ohos.data.preferences';
+import { LogUtil } from '@ohos/common';
+
+const TAG = 'MediaController : ';
+
+export class MediaController {
+ private mMediaLibrary: mediaLibrary.MediaLibrary = mediaLibrary.getMediaLibrary(globalThis.abilityContext);
+ private preferences?: data_preferences.Preferences;
+
+ constructor() {
+ this.initPreferences();
+ }
+
+ /**
+ * init Preferences
+ */
+ async initPreferences() {
+ LogUtil.info(`${TAG} initPreferences.`);
+ this.preferences = await data_preferences.getPreferences(globalThis.abilityContext, 'myRecorderStore');
+ }
+
+ /**
+ * save File Duration to preferences
+ *
+ * @param name
+ * @param value
+ */
+ async saveFileDuration(name: string, value: number) {
+ LogUtil.info(`${TAG} saveFileDuration. fileName : ${name}. duration:${value}`);
+ if (this.preferences) {
+ await this.preferences.put(name, value);
+ this.preferences.flush();
+ LogUtil.info(`${TAG} save File Duration end.`);
+ }
+ }
+}
+
+export default new MediaController();
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/src/main/ets/controller/RecordController.ets b/product/tablet/oh_modules/@ohos/recorder/src/main/ets/controller/RecordController.ets
new file mode 100644
index 0000000000000000000000000000000000000000..ec15a779f0a2967432f910a9e0b4ff8b7cd72c52
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/src/main/ets/controller/RecordController.ets
@@ -0,0 +1,189 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import media from '@ohos.multimedia.media';
+import { LogUtil } from '@ohos/common';
+import Notification from '@ohos.notification';
+import { BusinessError, Callback } from '@ohos.base'
+
+const NOTIFY_INTERVAL_MS = 60;
+const NOTIFY_ID = 10023;
+const TAG = 'RecordController : ';
+
+export enum RecordState {
+ IDLE,
+ RUNNING,
+ PAUSED,
+}
+
+export class RecordController {
+ private beforePauseTime: number = 0;
+ private startTimestamp: number = 0;
+ private notifierId: number = -1;
+ private state: string = '';
+ private config?: media.AVRecorderConfig;
+ private openedFileFd?: number;
+ private currentFilePath?: string;
+ private recorderDuration: number = 0;
+ private currentTimeMs: number = 0;
+ private audioRecorder?: media.AVRecorder;
+ private timeUpdateListener?: Callback;
+ private stateUpdateListener?: Callback;
+
+ /**
+ * Notification time update
+ */
+ private notifyTimeChanges() {
+ if (this.timeUpdateListener) {
+ this.timeUpdateListener(this.currentTimeMs);
+ }
+ }
+
+ /**
+ * Notification of status updates
+ */
+ private async notifyStateChanges() {
+ if (this.stateUpdateListener) {
+ LogUtil.info(`${TAG} state update. ${this.state}`);
+ this.stateUpdateListener(this.state);
+ }
+ }
+
+ /**
+ * Set the time update listener
+ *
+ * @param listener
+ */
+ public setTimeUpdateListener(tag: string, timeUpdateListener: Callback): void {
+ LogUtil.info(`${TAG} setTimeUpdateListener`);
+ this.timeUpdateListener = timeUpdateListener;
+ }
+
+ /**
+ * Set the status update listener
+ *
+ * @param listener
+ */
+ public setStateUpdateListener(tag: string, setStateUpdateListener: Callback): void {
+ LogUtil.info(`${TAG} setStateUpdateListener`);
+ this.stateUpdateListener = setStateUpdateListener;
+ }
+
+ /**
+ * init AudioRecorder
+ */
+ async initAudioRecorder() {
+ LogUtil.info(`${TAG} initAudioRecorder.`);
+ if (!this.audioRecorder) {
+ this.audioRecorder = await media.createAVRecorder();
+ }
+ this.setAVRecorderCallback(this.audioRecorder);
+ }
+
+ private setAVRecorderCallback(avRecorder: media.AVRecorder): void {
+ if (!avRecorder) {
+ return;
+ }
+ avRecorder.on('error', async (err: BusinessError) => {
+
+ });
+ avRecorder.on('stateChange', async (state: string, resaon: media.StateChangeReason) => {
+ this.state = state;
+ switch (state) {
+ case 'idle':
+ break;
+ case 'initialized':
+ break;
+ case 'started':
+ break;
+ case 'prepared':
+ break;
+ case 'paused':
+ break;
+ case 'completed':
+ break;
+ case 'stopped':
+ break;
+ case 'released':
+ break;
+ case 'released':
+ break;
+ default:
+ break
+ }
+ });
+ }
+
+ /**
+ * Gets the sound size of the recording
+ */
+ getSoundVolume() { //todo
+ return Math.random() * 100 + 5;
+ }
+
+ /**
+ * Recorder start
+ *
+ * @param pathName
+ */
+ startRecorder(tag: string, filefd: number, filePath: string, config: media.AVRecorderConfig,
+ recorderStateCallback: Callback, onErrorCallback?: Callback) {
+ if (this.audioRecorder) {
+ this.recorderDuration = 0;
+ this.currentFilePath = filePath;
+ this.config = config;
+ this.openedFileFd = filefd;
+ if (this.audioRecorder.state === 'idle') {
+ this.audioRecorder.prepare(config);
+ } else {
+ this.audioRecorder.reset();
+ }
+ LogUtil.info(`${TAG} audioRecorder prepare.`);
+ ;
+ } else {
+ LogUtil.error(`${TAG} case failed, audioRecorder is null.`);
+ }
+ }
+
+ /**
+ * Recorder pause
+ */
+ pause() {
+ if (this.audioRecorder) {
+ LogUtil.info(`${TAG} audioRecorder pause`);
+ this.audioRecorder.pause();
+ }
+ }
+
+ /**
+ * Recorder resume
+ */
+ resume() {
+ if (this.audioRecorder) {
+ LogUtil.info(`${TAG} audioRecorder resume`);
+ this.audioRecorder.resume();
+ }
+ }
+
+ /**
+ * Recorder stop
+ */
+ stop() {
+ if (this.audioRecorder) {
+ LogUtil.info(`${TAG} audioRecorder stop`);
+ this.audioRecorder.stop();
+ }
+ }
+}
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/src/main/ets/controller/StateController.ets b/product/tablet/oh_modules/@ohos/recorder/src/main/ets/controller/StateController.ets
new file mode 100644
index 0000000000000000000000000000000000000000..bf5bc9aaaa4630c8d59c43bfb9d42c7cf26c687d
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/src/main/ets/controller/StateController.ets
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { LogUtil } from '@ohos/common';
+import { BusinessError, Callback } from '@ohos.base'
+
+const TAG = 'ControlState : ';
+
+export enum ControlState {
+ START,
+ END,
+}
+
+export class StateController {
+ private state: number = 1;
+ private stateUpdateListener?: Callback;
+
+ /**
+ * Set the status update listener
+ *
+ * @param listener
+ */
+ public setStateUpdateListener(tag: number, setStateUpdateListener: Callback): void {
+ LogUtil.info(`${TAG} setStateUpdateListener`);
+ this.stateUpdateListener = setStateUpdateListener;
+ }
+
+ /**
+ * Notification of status updates
+ */
+ private async notifyStateChanges() {
+ if (this.stateUpdateListener) {
+ this.stateUpdateListener(this.state);
+ }
+ }
+
+ /**
+ * Announce the start of recording
+ */
+ public start() {
+ LogUtil.info(`${TAG} record start.`);
+ this.state = ControlState.START;
+ this.notifyStateChanges();
+ }
+
+ /**
+ * Announce the end of recording
+ */
+ public end() {
+ LogUtil.info(`${TAG} record end.`);
+ this.state = ControlState.END;
+ this.notifyStateChanges();
+ }
+}
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/src/main/ets/model/RecordData.ets b/product/tablet/oh_modules/@ohos/recorder/src/main/ets/model/RecordData.ets
new file mode 100644
index 0000000000000000000000000000000000000000..ab6a4855779936bcd3eb2a05b85087b93ac11e00
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/src/main/ets/model/RecordData.ets
@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2022 HiHope Open Source Organization.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { MediaController } from '../controller/MediaController';
+import mediaLibrary from '@ohos.multimedia.mediaLibrary';
+
+export class RecordData {
+ fileAsset: string = '';
+ title: string = '';
+ duration: number = 0;
+ date: number = 0;
+
+ constructor(fileAsset: number, date: number, title: string) {
+ if (fileAsset) {
+ if (fileAsset > 0) {
+ this.duration = fileAsset;
+ } else {
+ this.duration = 0;
+ }
+ if (date > 0) {
+ this.date = date;
+ } else {
+ this.date = 0;
+ }
+ this.title = title;
+ } else {
+ this.duration = 0;
+ this.title = '';
+ }
+ }
+}
\ No newline at end of file
diff --git a/product/tablet/oh_modules/@ohos/recorder/src/main/module.json5 b/product/tablet/oh_modules/@ohos/recorder/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..ed1e0395a095843abbd6047df13d59d682c9c980
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/src/main/module.json5
@@ -0,0 +1,11 @@
+{
+ "module": {
+ "name": "recorder",
+ "type": "har",
+ "deviceTypes": [
+ "default",
+ "tablet"
+ ],
+ "uiSyntax": "ets"
+ }
+}
diff --git a/product/tablet/oh_modules/@ohos/recorder/src/main/resources/base/element/string.json b/product/tablet/oh_modules/@ohos/recorder/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed
--- /dev/null
+++ b/product/tablet/oh_modules/@ohos/recorder/src/main/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "page_show",
+ "value": "page from npm package"
+ }
+ ]
+}
diff --git a/product/tablet/src/main/ets/Application/MyAbilityStage.ts b/product/tablet/src/main/ets/Application/MyAbilityStage.ts
index 0a9efc1ed476ee2dfdca792a1632b37b99922670..06ad1b3deebdd690fe6a9b8dd45a97c3ef544e8a 100644
--- a/product/tablet/src/main/ets/Application/MyAbilityStage.ts
+++ b/product/tablet/src/main/ets/Application/MyAbilityStage.ts
@@ -13,7 +13,7 @@
* limitations under the License.
*/
-import AbilityStage from "@ohos.application.AbilityStage"
+import AbilityStage from "@ohos.app.ability.AbilityStage"
export default class MyAbilityStage extends AbilityStage {
onCreate() {
diff --git a/product/tablet/src/main/ets/MainAbility/MainAbility.ts b/product/tablet/src/main/ets/MainAbility/MainAbility.ts
index 67501c1826d9d010967d72a2428c02442e5d1423..a0be8b456987bbf9967475facaeaa8233b98a566 100644
--- a/product/tablet/src/main/ets/MainAbility/MainAbility.ts
+++ b/product/tablet/src/main/ets/MainAbility/MainAbility.ts
@@ -13,14 +13,13 @@
* limitations under the License.
*/
-import Ability from '@ohos.application.Ability'
+import Ability from '@ohos.app.ability.Ability'
import Notification from '@ohos.notification';
export default class MainAbility extends Ability {
onCreate(want, launchParam) {
console.log("[Demo] MainAbility onCreate")
globalThis.abilityWant = want;
- globalThis.abilityContext = this.context;
}
onDestroy() {
@@ -31,17 +30,6 @@ export default class MainAbility extends Ability {
onWindowStageCreate(windowStage) {
// Main window is created, set main page for this ability
console.log("[Demo] MainAbility onWindowStageCreate")
- this.context.requestPermissionsFromUser(['ohos.permission.MICROPHONE', 'ohos.permission.WRITE_MEDIA', 'ohos.permission.READ_MEDIA']).then(() => {
- Notification.requestEnableNotification().then(() => {
- windowStage.loadContent("pages/index", (err, data) => {
- if (err.code) {
- console.error('Failed to load the content. Cause:' + JSON.stringify(err));
- return;
- }
- console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data))
- });
- })
- })
}
onWindowStageDestroy() {
diff --git a/product/tablet/src/main/ets/pages/RecordingPage.ets b/product/tablet/src/main/ets/pages/RecordingPage.ets
index f352c8b972a6eaf623dd618f9447fc647f984cb6..8f4da50425a0e57fe337b9dfc59698eabcefe1cd 100644
--- a/product/tablet/src/main/ets/pages/RecordingPage.ets
+++ b/product/tablet/src/main/ets/pages/RecordingPage.ets
@@ -29,23 +29,11 @@ export struct RecordingPage {
@State currentTime: number = 0
@State state: RecordState = RecordState.IDLE
private recordController: RecordController = new RecordController()
- @State fileAsset: mediaLibrary.FileAsset = undefined
private stateController = new StateController()
heightList: Array = []
async aboutToAppear() {
- let that = this
- this.recordController.setTimeUpdateListener((currentTimeMs: number) => {
- if (Math.floor(currentTimeMs / (TIME_COUNT / 2 * 1000 * TIME_INTERVAL_S / VOICE_FREQUENCY)) - Math.floor(this.currentTime / (TIME_COUNT / 2 * 1000 * TIME_INTERVAL_S / VOICE_FREQUENCY)) == 1) {
- that.heightList.splice(0, 1)
- that.heightList.push(this.recordController.getSoundVolume())
- }
- this.currentTime = currentTimeMs
- })
- this.recordController.setStateUpdateListener((state) => {
- this.state = state
- })
- this.initHeightList()
+
}
initHeightList() {
@@ -77,7 +65,7 @@ export struct RecordingPage {
Stack({ alignContent: Alignment.Top }) {
Column() {
Row() {
- ForEach(Array.from(Array(TIME_COUNT + 1).keys()), (item) => {
+ ForEach(Array.from(Array(TIME_COUNT + 1).keys()), (item:number) => {
Column() {
Text(Util.timeFormat(((item - (TIME_COUNT - 1) / 2) * 1000 * TIME_INTERVAL_S + Math.floor(this.currentTime / (1000 * TIME_INTERVAL_S)) * (1000 * TIME_INTERVAL_S)), false))
.textAlign(TextAlign.Center)
@@ -85,19 +73,19 @@ export struct RecordingPage {
.fontSize($r("app.float.font_10"))
.opacity($r("app.float.opacity_6"))
Row() {
- ForEach(Array.from(Array(5).keys()), (scaleItem) => {
+ ForEach(Array.from(Array(5).keys()), (scaleItem:number) => {
Rect()
.width($r("app.float.wh_value_1"))
.fill($r("app.color.text_color"))
.height(scaleItem == 2 ? $r("app.float.wh_value_10") : $r("app.float.wh_value_5"))
.opacity(scaleItem == 2 ? $r("app.float.opacity_4") : $r("app.float.opacity_2"))
- }, scaleItem => scaleItem)
+ }, (scaleItem:number) => scaleItem+'')
}.width(ConfigData.WH_100_100)
.alignItems(VerticalAlign.Top)
.height($r("app.float.wh_value_10"))
.justifyContent(FlexAlign.SpaceAround)
}.width((100 / TIME_COUNT) + "%")
- }, item => item)
+ }, (item:number) => item+'')
}
.offset({
x: (-(100 / TIME_COUNT) * (this.currentTime % (TIME_INTERVAL_S * 1000) / (TIME_INTERVAL_S * 1000))) + "%"
@@ -106,13 +94,13 @@ export struct RecordingPage {
Row() {
Row() {
Row() {
- ForEach(Array.from(Array(VOICE_FREQUENCY).keys()), (item) => {
+ ForEach(Array.from(Array(VOICE_FREQUENCY).keys()), (item:number) => {
Rect()
.width($r("app.float.wh_value_1"))
.fill($r("app.color.text_color"))
.height(this.heightList[item] * 0.5)
.opacity($r("app.float.opacity_2"))
- }, item => item)
+ }, (item:number) => item+'')
}.width(ConfigData.WH_100_100)
.justifyContent(FlexAlign.SpaceAround)
.offset({
@@ -189,20 +177,12 @@ export struct RecordingPage {
if (this.state == RecordState.IDLE) {
let hasCall = await call.hasCall()
if (hasCall) {
- prompt.showToast({ message: $r('app.string.has_call_hint') })
} else {
this.stateController.start()
this.recordController.initAudioRecorder()
- this.fileAsset = await MediaController.createAudioFile()
- let fd = await this.fileAsset.open('Rw')
- this.recordController.startRecorder(`fd://${fd}`)
}
} else {
- this.recordController.stop(() => {
- this.initHeightList()
- MediaController.saveFileDuration(this.fileAsset.title, this.currentTime)
- this.stateController.end()
- })
+ this.recordController.stop()
}
})
diff --git a/product/tablet/src/main/ets/pages/recordList.ets b/product/tablet/src/main/ets/pages/recordList.ets
index 9a5f73b760f40c0d643f874bd108680b470394d2..de990207c61bc9e727507cd2301a45e7274d23e8 100644
--- a/product/tablet/src/main/ets/pages/recordList.ets
+++ b/product/tablet/src/main/ets/pages/recordList.ets
@@ -25,49 +25,12 @@ export struct recordList {
private audioController: AudioController = new AudioController()
@State state: AudioState = AudioState.IDLE;
@State filterText: string = "";
- private deleteRecord: RecordData = undefined
- private stateController = new StateController()
- @State disable: boolean = false
- confirm: () => void = () => {
- MediaController.deleteRecord(this.deleteRecord.fileAsset.uri, () => {
- for (let i = this.recordList.length - 1;i >= 0; i--) {
- if (this.deleteRecord.fileAsset.uri == this.recordList[i].fileAsset.uri) {
- this.recordList.splice(i, 1)
- }
- }
- })
- }
- dialogController: CustomDialogController = new CustomDialogController({
- builder: DeleteRecordDialog({ deleteRecordTitle: this.deleteRecord.title, confirm: this.confirm }),
- autoCancel: true,
- alignment: DialogAlignment.Bottom,
- offset: { dy: -16, dx: 0 }
- })
-
- async getAudios() {
- this.recordList = await MediaController.queryAllAudios()
- }
+ //private deleteRecord: RecordData;
+ private stateController = new StateController();
+ @State disable: boolean = false;
aboutToAppear() {
- this.getAudios()
- this.stateController.setStateUpdateListener((state) => {
- if (state == ControlState.START) {
- this.disable = true
- this.audioController.stop()
- } else {
- this.disable = false
- this.getAudios()
- }
- })
- this.audioController.setTimeUpdateListener((currentTime: number) => {
- this.currentTime = currentTime
- })
- this.audioController.setStateUpdateListener((state: AudioState) => {
- if (state == AudioState.IDLE) {
- this.selectedIndex = -1
- }
- this.state = state
- })
+ ;
}
build() {
@@ -118,19 +81,17 @@ export struct recordList {
Column() {
List() {
- ForEach([...this.recordList].reverse().map((value, index) => {
- return { i: index, data: value }
- }), (item) => {
+ ForEach([...this.recordList].reverse(), (item:RecordData, index:number) => {
ListItem() {
Column() {
Row() {
Column() {
- Text(item.data.title)
+ Text(item.title)
.fontColor($r("app.color.text_color"))
.fontSize($r("app.float.font_16"))
.width($r("app.float.wh_value_105"))
.lineHeight($r("app.float.wh_value_10_5"))
- Text(Util.getDateFormat(item.data.date))
+ Text(Util.getDateFormat(item.date))
.fontColor($r("app.color.text_color"))
.opacity($r("app.float.opacity_6"))
.fontSize($r("app.float.font_14"))
@@ -139,12 +100,12 @@ export struct recordList {
}
Row() {
- Text(Util.timeFormat(item.data.duration))
+ Text(Util.timeFormat(item.duration))
.fontColor($r("app.color.text_color"))
.opacity($r("app.float.opacity_6"))
.fontSize($r("app.float.font_14"))
.margin({ right: $r("app.float.distance_2") })
- Image((item.i == this.selectedIndex && this.state == AudioState.RUNNING) ? $r("app.media.ic_record_stop") : $r("app.media.ic_record_play"))
+ Image((index == this.selectedIndex && this.state == AudioState.RUNNING) ? $r("app.media.ic_record_stop") : $r("app.media.ic_record_play"))
.width($r("app.float.wh_value_12"))
.height($r("app.float.wh_value_12"))
}
@@ -154,9 +115,9 @@ export struct recordList {
.justifyContent(FlexAlign.SpaceBetween)
.padding({ left: $r("app.float.distance_12"), right: $r("app.float.distance_12") })
.onClick(() => {
- if (this.selectedIndex != item.i || this.state == AudioState.IDLE) {
- this.selectedIndex = item.i
- this.audioController.initAudioPlayer(item.data.fileAsset, () => {
+ if (this.selectedIndex != index || this.state == AudioState.IDLE) {
+ this.selectedIndex = index
+ this.audioController.initAudioPlayer(item.fileAsset, () => {
this.audioController.play()
})
} else if (this.state == AudioState.RUNNING) {
@@ -169,17 +130,15 @@ export struct recordList {
LongPressGesture()
.onAction(() => {
this.audioController.stop()
- this.deleteRecord = item.data
- this.dialogController.open()
})
)
- if (this.selectedIndex == item.i) {
+ if (this.selectedIndex == index) {
Column() {
Slider({
value: this.currentTime,
min: 0,
- max: item.data.duration,
+ max: item.duration,
style: SliderStyle.OutSet
})
.trackThickness($r("app.float.wh_value_2"))
@@ -199,7 +158,7 @@ export struct recordList {
.opacity($r("app.float.opacity_6"))
.fontSize($r("app.float.font_10"))
.margin({ right: $r("app.float.distance_2") })
- Text(Util.timeFormat(item.data.duration))
+ Text(Util.timeFormat(item.duration))
.fontColor($r("app.color.text_color"))
.opacity($r("app.float.opacity_6"))
.fontSize($r("app.float.font_10"))
@@ -214,8 +173,8 @@ export struct recordList {
.width(ConfigData.WH_100_100)
}
}
- }.visibility(item.data.title.indexOf(this.filterText) >= 0 ? Visibility.Visible : Visibility.None)
- }, item => item.i)
+ }.visibility(item.title.indexOf(this.filterText) >= 0 ? Visibility.Visible : Visibility.None)
+ }, (index:number) => index+'')
}
.width(ConfigData.WH_100_100)
@@ -244,8 +203,8 @@ export struct recordList {
@CustomDialog
struct DeleteRecordDialog {
private controller: CustomDialogController
- private deleteRecordTitle: string
- private confirm: () => void
+ private deleteRecordTitle: string = '';
+ private confirm: () =>void = ()=>{};
build() {
Column() {
diff --git a/product/tablet/src/main/module.json5 b/product/tablet/src/main/module.json5
index 6a30a379752a06bb87b982e16b0c00d685259c05..fe25f59e215c0c56f1dd7ce11e8df07428d0248e 100644
--- a/product/tablet/src/main/module.json5
+++ b/product/tablet/src/main/module.json5
@@ -2,7 +2,7 @@
"module": {
"name": "tablet",
"type": "entry",
- "srcEntrance": "./ets/Application/MyAbilityStage.ts",
+ "srcEntry": "./ets/Application/MyAbilityStage.ts",
"description": "$string:tablet_desc",
"mainElement": "MainAbility",
"deviceTypes": [
@@ -15,7 +15,7 @@
"abilities": [
{
"name": "MainAbility",
- "srcEntrance": "./ets/MainAbility/MainAbility.ts",
+ "srcEntry": "./ets/MainAbility/MainAbility.ts",
"description": "$string:MainAbility_desc",
"icon": "$media:icon",
"label": "$string:MainAbility_label",
@@ -35,15 +35,15 @@
}
],
"requestPermissions": [
- {
- "name": "ohos.permission.MICROPHONE"
- },
- {
- "name": "ohos.permission.WRITE_MEDIA"
- },
- {
- "name": "ohos.permission.READ_MEDIA"
- }
+ //{
+ // "name": "ohos.permission.MICROPHONE"
+ //},
+ //{
+ // "name": "ohos.permission.WRITE_MEDIA"
+ //},
+ //{
+ // "name": "ohos.permission.READ_MEDIA"
+ //}
]
}
}
\ No newline at end of file