diff --git a/build-profile.json5 b/build-profile.json5 index a815fd0..10af8c6 100644 --- a/build-profile.json5 +++ b/build-profile.json5 @@ -4,13 +4,13 @@ { "name": "default", "material": { - "certpath": "C:\\Users\\surenjun\\.ohos\\config\\openharmony\\auto_ohos_default_end2_bak_com.oh.dts.cer", - "storePassword": "0000001BBCF008AF436022E84525958DDA30DAACBAE95FB89880984155936D5A2B2211EBFC642FCC2C063B", + "certpath": "/Users/wangzhongjie/.ohos/config/openharmony/auto_ohos_default_subject-two_com.oh.dts.cer", + "storePassword": "0000001A3E7D97C4BC5819BCBC0470AB1397AAD09AC6E70069CFC6FD7D21A58A50AA6EE3FEBCDA027D71", "keyAlias": "debugKey", - "keyPassword": "0000001B43018ED537D1DAF50E0FBEDF8E721D4B33B58ED0429751E6224D301D25C6BB44B66F90B57FFDEF", - "profile": "C:\\Users\\surenjun\\.ohos\\config\\openharmony\\auto_ohos_default_end2_bak_com.oh.dts.p7b", + "keyPassword": "0000001A764ACBDC861BE169BE8B85E333F52659116CD5B8F12254C0F8F893E26884787B99199D49B10C", + "profile": "/Users/wangzhongjie/.ohos/config/openharmony/auto_ohos_default_subject-two_com.oh.dts.p7b", "signAlg": "SHA256withECDSA", - "storeFile": "C:\\Users\\surenjun\\.ohos\\config\\openharmony\\auto_ohos_default_end2_bak_com.oh.dts.p12" + "storeFile": "/Users/wangzhongjie/.ohos/config/openharmony/auto_ohos_default_subject-two_com.oh.dts.p12" } } ], diff --git a/entry/oh-package-lock.json5 b/entry/oh-package-lock.json5 new file mode 100644 index 0000000..bc40219 --- /dev/null +++ b/entry/oh-package-lock.json5 @@ -0,0 +1,13 @@ +{ + "lockfileVersion": 1, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6" + }, + "packages": { + "@ohos/hypium@1.0.6": { + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", + "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==" + } + } +} \ No newline at end of file diff --git a/entry/oh-package.json5 b/entry/oh-package.json5 new file mode 100644 index 0000000..f1b2443 --- /dev/null +++ b/entry/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "license": "", + "devDependencies": { + "@ohos/hypium": "1.0.6" + }, + "author": "", + "name": "myapplication", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": {} +} diff --git a/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/CHANGELOG.md b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/CHANGELOG.md new file mode 100644 index 0000000..fb0366d --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/CHANGELOG.md @@ -0,0 +1,45 @@ +## 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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/README.md b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/README.md new file mode 100644 index 0000000..743361c --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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.6" +} +``` +注: +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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/index.d.ts b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/index.d.ts new file mode 100644 index 0000000..b0b4394 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/index.ets b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/index.ets new file mode 100644 index 0000000..3c3fe31 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/index.ets @@ -0,0 +1,92 @@ +/* + * 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 './src/main/core'; +import {DEFAULT, TestType, Size, Level} 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('parameters:' + JSON.stringify(testParameters)); + configService.setConfig(testParameters); + + testsuite(); + if (Object.prototype.hasOwnProperty.call(globalThis, 'setupUiTestEnvironment')) { + globalThis.setupUiTestEnvironment().then(() => { + console.info('UiTestKit::after run uitest setup, start run testcases'); + core.execute(abilityDelegator); + }).catch((error) => { + console.error('UiTestKit:: call setupUiTestEnvironment failure:' + error); + core.execute(abilityDelegator); + }); + } else { + console.info('UiTestKit:: no need to setup uitest, start run testcases'); + 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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/index.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/index.js new file mode 100644 index 0000000..3c3fe31 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/index.js @@ -0,0 +1,92 @@ +/* + * 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 './src/main/core'; +import {DEFAULT, TestType, Size, Level} 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('parameters:' + JSON.stringify(testParameters)); + configService.setConfig(testParameters); + + testsuite(); + if (Object.prototype.hasOwnProperty.call(globalThis, 'setupUiTestEnvironment')) { + globalThis.setupUiTestEnvironment().then(() => { + console.info('UiTestKit::after run uitest setup, start run testcases'); + core.execute(abilityDelegator); + }).catch((error) => { + console.error('UiTestKit:: call setupUiTestEnvironment failure:' + error); + core.execute(abilityDelegator); + }); + } else { + console.info('UiTestKit:: no need to setup uitest, start run testcases'); + 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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/oh-package.json5 b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/oh-package.json5 new file mode 100644 index 0000000..84d3f85 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/oh-package.json5 @@ -0,0 +1,11 @@ +{ + "name": "@ohos/hypium", + "version": "1.0.6", + "description": "A unit test framework for OpenHarmony application", + "main": "index.js", + "keywords": [], + "author": "huawei", + "license": "Apache-2.0", + "dependencies": { + } +} diff --git a/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/Constant.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/Constant.js new file mode 100644 index 0000000..f182910 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/Constant.js @@ -0,0 +1,47 @@ +/* + * 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 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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/core.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/core.js new file mode 100644 index 0000000..cfcb5f1 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/event.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/event.js new file mode 100644 index 0000000..1333a1c --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/interface.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/interface.js new file mode 100644 index 0000000..40398c8 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/ExpectExtend.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/ExpectExtend.js new file mode 100644 index 0000000..d10d15e --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertClose.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertClose.js new file mode 100644 index 0000000..63635be --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertContain.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertContain.js new file mode 100644 index 0000000..7fba0d9 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertFail.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertFail.js new file mode 100644 index 0000000..8ab4ac5 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertFalse.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertFalse.js new file mode 100644 index 0000000..c5008e9 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertInstanceOf.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertInstanceOf.js new file mode 100644 index 0000000..1e11b93 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertLarger.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertLarger.js new file mode 100644 index 0000000..a74f4a8 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertLargerOrEqual.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertLargerOrEqual.js new file mode 100644 index 0000000..e847e6c --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertLess.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertLess.js new file mode 100644 index 0000000..17e84b0 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertLessOrEqual.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertLessOrEqual.js new file mode 100644 index 0000000..f754f97 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertNaN.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertNaN.js new file mode 100644 index 0000000..8d45d6a --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertNegUnlimited.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertNegUnlimited.js new file mode 100644 index 0000000..ceac555 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertNull.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertNull.js new file mode 100644 index 0000000..53a7bad --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPosUnlimited.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPosUnlimited.js new file mode 100644 index 0000000..6e68c0e --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsPending.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsPending.js new file mode 100644 index 0000000..7e2ca2c --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejected.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejected.js new file mode 100644 index 0000000..eb8e65c --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWith.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWith.js new file mode 100644 index 0000000..48eaf78 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWithError.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWithError.js new file mode 100644 index 0000000..334a3d3 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWithError.js @@ -0,0 +1,103 @@ +/* + * 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 + '.'}; + } else { + 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 + '.' + }; + } else { + 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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolved.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolved.js new file mode 100644 index 0000000..855426c --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolvedWith.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolvedWith.js new file mode 100644 index 0000000..d5eb01e --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertThrowError.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertThrowError.js new file mode 100644 index 0000000..749cab0 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertUndefined.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertUndefined.js new file mode 100644 index 0000000..61f092d --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/DeepTypeUtils.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/DeepTypeUtils.js new file mode 100644 index 0000000..b0be667 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/DeepTypeUtils.js @@ -0,0 +1,138 @@ +/* + * 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 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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/assertDeepEquals.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/assertDeepEquals.js new file mode 100644 index 0000000..4d991b4 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/assertDeepEquals.js @@ -0,0 +1,311 @@ +/* + * 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{ + actualMsg = JSON.stringify(actualValue); + } + if(bClassName == "[object Function]") { + expectMsg = "expected Function" + }else if(bClassName == "[object Promise]") { + expectMsg = "expected Promise" + }else if(aClassName == "[object Set]" || bClassName == "[object Map]") { + expectMsg = JSON.stringify(Array.from(expected)); + }else if(aClassName == "[object RegExp]") { + expectMsg = JSON.stringify(expected.source.replace("\\",""));; + } + 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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/isPromiseLike.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/isPromiseLike.js new file mode 100644 index 0000000..015ab19 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/config/DataDriver.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/config/DataDriver.js new file mode 100644 index 0000000..639dffc --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/config/Filter.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/config/Filter.js new file mode 100644 index 0000000..0ca3b4f --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/config/configService.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/config/configService.js new file mode 100644 index 0000000..745f137 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/config/configService.js @@ -0,0 +1,292 @@ +/* + * 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 {ClassFilter, NotClassFilter, SuiteAndItNameFilter, TestTypesFilter} from './Filter'; +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('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('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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/coverage/coverageCollect.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/coverage/coverageCollect.js new file mode 100644 index 0000000..4707dea --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/coverage/coverageCollect.js @@ -0,0 +1,30 @@ +/* + * 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++) { + await SysTestKit.print(`${OHOS_REPORT_COVERAGE_DATA} ${strJson.substring(count * maxLen, (count + 1) * maxLen)}`); + } +} \ No newline at end of file diff --git a/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/kit/SysTestKit.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/kit/SysTestKit.js new file mode 100644 index 0000000..d73d46d --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/kit/SysTestKit.js @@ -0,0 +1,88 @@ +/* + * 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 SysTestKit { + + static delegator = null; + static systemTime = null; + + constructor() { + this.id = 'sysTestKit'; + this.index = 0; + } + + static actionStart(tag) { + console.info(JSON.stringify(tag)); + var message = '\n' + 'OHOS_REPORT_ACTIONSTART: ' + JSON.stringify(tag) + '\n'; + SysTestKit.print(message); + console.info(tag + ' actionStart print success'); + } + + static actionEnd(tag) { + console.info(JSON.stringify(tag)); + var message = '\n' + 'OHOS_REPORT_ACTIONEND: ' + JSON.stringify(tag) + '\n'; + SysTestKit.print(message); + console.info(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(`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(`systemTime.getRealTime success data: ${JSON.stringify(time)}`); + currentTime = time; + }).catch((error) => { + console.error(`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('existKeyword CallBack: err : ' + JSON.stringify(error)); + console.info('existKeyword CallBack: data : ' + JSON.stringify(data)); + resolve(parseInt(data.stdResult) > 3 ? true : false); + }); + }); +} + +export default SysTestKit; \ No newline at end of file diff --git a/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/ArgumentMatchers.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/ArgumentMatchers.js new file mode 100644 index 0000000..6a9d7aa --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/ExtendInterface.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/ExtendInterface.js new file mode 100644 index 0000000..c6a866a --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/MockKit.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/MockKit.js new file mode 100644 index 0000000..a234624 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/MockKit.js @@ -0,0 +1,256 @@ +/* + * 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 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 = null; + this.mockObj = null; + this.recordMockedMethod = new Map(); + } + + init() { + this.reset(); + } + + reset() { + this.mFunctions = []; + this.stubs = {}; + this.recordCalls = {}; + this.currentSetKey = null; + 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 = 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; + + if (this.currentSetKey && (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.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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/VerificationMode.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/VerificationMode.js new file mode 100644 index 0000000..7bd04c8 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/VerificationMode.js @@ -0,0 +1,49 @@ +/* + * 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 {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/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/report/OhReport.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/report/OhReport.js new file mode 100644 index 0000000..da120dd --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/report/OhReport.js @@ -0,0 +1,148 @@ +/* + * 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 SysTestKit from "../kit/SysTestKit"; +import {collectCoverageData} from '../coverage/coverageCollect'; + +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('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(this.suiteService.getCurrentRunningSuite().description + ' suiteStart print success'); + } + } + + async suiteDone() { + if (this.abilityDelegatorArguments !== null) { + let message = '\n' + 'OHOS_REPORT_STATUS: class=' + this.suiteService.getCurrentRunningSuite().description; + message += '\n' + 'OHOS_REPORT_STATUS: suiteconsuming=' + this.suiteService.getCurrentRunningSuite().duration + '\n'; + console.info(message); + await SysTestKit.print(message); + console.info(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(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.result) { + if (this.specService.currentRunningSpec.result.failExpects.length > 0) { + this.specService.currentRunningSpec.result.failExpects.forEach(failExpect => { + errorMsg = failExpect.message || ('expect ' + failExpect.actualValue + ' ' + failExpect.checkFunc + ' ' + (failExpect.expectValue)); + }); + 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(this.specService.currentRunningSpec.description + ' specDone end print success'); + } + } +} + +export default OhReport; diff --git a/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/report/ReportExtend.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/report/ReportExtend.js new file mode 100644 index 0000000..852fbcd --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/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}` : '/>'; + return xml; +} + +export default ReportExtend; diff --git a/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/service.js b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/service.js new file mode 100644 index 0000000..e55a2e4 --- /dev/null +++ b/entry/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/service.js @@ -0,0 +1,929 @@ +/* + * 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 SysTestKit from "./module/kit/SysTestKit"; + +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('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.result.failExpects.length > 0) { + obj.failure++; + } else if (itItem.result.pass === true) { + obj.pass++; + } + } + } + + obj.duration += suite.duration; + + if (suite.childSuites.length > 0) { + for (const suiteItem of suite.childSuites) { + this.traversalResults(suiteItem, obj, breakOnError); + } + } + } + + 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('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; + } + + 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 asyncRun(coreContext) { + const suiteService = coreContext.getDefaultService('suite'); + suiteService.setCurrentRunningSuite(this); + suiteService.suitesStack.push(this); + if (this.description !== '') { + await coreContext.fireEvents('suite', 'suiteStart', this); + } + await this.runAsyncHookFunc('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 i = 0; i < this.specs.length; i++) { + // 遇错即停模式,发现用例有问题,直接返回,不在执行后面的it + let isBreakOnError = this.isRun(coreContext); + if (isBreakOnError) { + console.log("break description :" + this.description); + break; + } + await this.runAsyncHookFunc('beforeEach'); + await this.specs[i].asyncRun(coreContext); + await this.runAsyncHookFunc('afterEach'); + } + } + + if (this.childSuites.length > 0) { + for (let i = 0; i < this.childSuites.length; i++) { + // 遇错即停模式, 发现用例有问题,直接返回,不在执行后面的description + let isBreakOnError = this.isRun(coreContext); + if (isBreakOnError) { + console.log("break description :" + this.description); + break; + } + await this.childSuites[i].asyncRun(coreContext); + } + } + + await this.runAsyncHookFunc('afterAll'); + 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(e); + } + }); + } + } + + runAsyncHookFunc(hookName) { + if (this[hookName] && this[hookName].length > 0) { + return new Promise(async resolve => { + for (let i = 0; i < this[hookName].length; i++) { + try { + await this[hookName][i](); + } catch (e) { + console.error(e); + } + } + resolve(); + }); + } + } +}; + +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('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('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.result = { + failExpects: [], + passExpects: [] + }; + this.error = undefined; + this.duration = 0; + this.startTime = 0; + this.isExecuted = false; // 当前用例是否执行 + } + + setResult(coreContext) { + const specService = coreContext.getDefaultService('spec'); + if (this.result.failExpects.length > 0) { + this.result.pass = false; + specService.setStatus(true); + } else { + this.result.pass = true; + } + console.info('testcase ' + this.description + ' result:' + this.result.pass); + } + + 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('[suite params] ' + JSON.stringify(suiteParams)); + console.info('[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(coreContext); + } catch (e) { + this.error = e; + specService.setStatus(true); + } + coreContext.fireEvents('spec', 'specDone', this); + } + + async asyncRun(coreContext) { + const specService = coreContext.getDefaultService('spec'); + specService.setCurrentRunningSpec(this); + + await coreContext.fireEvents('spec', 'specStart', this); + try { + let dataDriver = coreContext.getServices('dataDriver'); + if (typeof dataDriver === 'undefined') { + await this.fn(); + this.setResult(coreContext); + } else { + let suiteParams = dataDriver.dataDriver.getSuiteParams(); + let 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(); + this.setResult(coreContext); + } else if (specParams.length === 0) { + await this.fn(suiteParams); + this.setResult(coreContext); + } else { + for (const paramItem of specParams) { + await this.fn(Object.assign({}, paramItem, suiteParams)); + this.setResult(coreContext); + } + } + } + } catch (e) { + if (e instanceof AssertException) { + this.fail = e; + specService.setStatus(true); + } else { + this.error = e; + specService.setStatus(true); + } + } + this.isExecuted = true; + await coreContext.fireEvents('spec', 'specDone', this); + } + + filterCheck(coreContext) { + const specService = coreContext.getDefaultService('spec'); + specService.setCurrentRunningSpec(this); + return true; + } + + addExpectationResult(expectResult) { + if (this.result.failExpects.length === 0) { + this.result.failExpects.push(expectResult); + } + throw new AssertException(expectResult.message); + } +}; + +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(); + 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) { + currentRunningSpec.addExpectationResult(result); + } + }); + }; + } 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) { + currentRunningSpec.addExpectationResult(result); + } + }; + } + } + 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('[start] start run suites'); + } + + async suiteStart() { + console.info('[suite start]' + this.suiteService.getCurrentRunningSuite().description); + } + + async specStart() { + console.info('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.result) { + if (spec.result.failExpects.length > 0) { + this.formatPrint('fail', spec.description + ' ; consuming ' + spec.duration + 'ms'); + spec.result.failExpects.forEach(failExpect => { + msg = failExpect.message || ('expect ' + failExpect.actualValue + ' ' + + failExpect.checkFunc + ' ' + (failExpect.expectValue)); + this.formatPrint('failDetail', msg); + }); + } else { + this.formatPrint('pass', spec.description + ' ; consuming ' + spec.duration + 'ms'); + } + } + this.formatPrint(this.specService.currentRunningSpec.error, msg); + } + + suiteDone() { + let suite = this.suiteService.currentRunningSuite; + console.info(`[suite end] ${suite.description} consuming ${suite.duration} ms`); + } + + 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(msg); + console.info('[end] run suites end'); + } + + incorrectFormat() { + if (this.coreContext.getDefaultService('config').filterValid.length !== 0) { + this.coreContext.getDefaultService('config').filterValid.forEach(function (item) { + console.info('this param ' + item + ' is invalid'); + }); + } + } + + formatPrint(type, msg) { + switch (type) { + case 'pass': + console.info('[pass]' + msg); + break; + case 'fail': + console.info('[fail]' + msg); + break; + case 'failDetail': + console.info('[failDetail]' + msg); + break; + case 'error': + console.info('[error]' + msg); + break; + case 'errorDetail': + console.info('[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/entry/oh_modules/.ohpm/oh_modules/@ohos/hypium b/entry/oh_modules/.ohpm/oh_modules/@ohos/hypium new file mode 120000 index 0000000..e3f4a5c --- /dev/null +++ b/entry/oh_modules/.ohpm/oh_modules/@ohos/hypium @@ -0,0 +1 @@ +../../@ohos+hypium@1.0.6/oh_modules/@ohos/hypium \ No newline at end of file diff --git a/entry/oh_modules/@ohos/hypium b/entry/oh_modules/@ohos/hypium new file mode 120000 index 0000000..ee523c7 --- /dev/null +++ b/entry/oh_modules/@ohos/hypium @@ -0,0 +1 @@ +../.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium \ No newline at end of file diff --git a/entry/src/main/module.json5 b/entry/src/main/module.json5 index 6e114dc..473978f 100644 --- a/entry/src/main/module.json5 +++ b/entry/src/main/module.json5 @@ -11,7 +11,6 @@ "deliveryWithInstall": true, "installationFree": false, "pages": "$profile:main_pages", - "abilities": [ { "name": "EntryAbility", @@ -34,17 +33,12 @@ ] } ], - "requestPermissions":[ - + "requestPermissions": [ { "name": "ohos.permission.INTERNET" }, - { - "name": "ohos.permission.GET_NETWORK_INFO" - }, { "name": "ohos.permission.CAMERA", - }, { "name": "ohos.permission.GET_WIFI_INFO" @@ -70,32 +64,32 @@ { "name": "ohos.permission.MEDIA_LOCATION" }, - { - "name": "ohos.permission.WRITE_MEDIA" - }, - { - "name": "ohos.permission.READ_MEDIA" - }, -// { -// "name": "ohos.permission.READ_MEDIA", -// "reason": "$string:module_desc", -// "usedScene": { -// "abilities": [ -// "MainAbility" -// ], -// "when": "always" -// } -// }, -// { -// "name": "ohos.permission.WRITE_MEDIA", -// "reason": "$string:module_desc", -// "usedScene": { -// "abilities": [ -// "MainAbility" -// ], -// "when": "always" -// } -// }, + { + "name": "ohos.permission.WRITE_MEDIA" + }, + { + "name": "ohos.permission.READ_MEDIA" + }, + // { + // "name": "ohos.permission.READ_MEDIA", + // "reason": "$string:module_desc", + // "usedScene": { + // "abilities": [ + // "MainAbility" + // ], + // "when": "always" + // } + // }, + // { + // "name": "ohos.permission.WRITE_MEDIA", + // "reason": "$string:module_desc", + // "usedScene": { + // "abilities": [ + // "MainAbility" + // ], + // "when": "always" + // } + // }, { "name": "ohos.permission.FILE_ACCESS_MANAGER", "reason": "$string:module_desc", diff --git a/entry/src/ohosTest/module.json5 b/entry/src/ohosTest/module.json5 index 35d4eed..d41d683 100644 --- a/entry/src/ohosTest/module.json5 +++ b/entry/src/ohosTest/module.json5 @@ -37,14 +37,6 @@ { "name": "ohos.permission.INTERNET" }, - { - "name": "ohos.permission.GET_WIFI_INFO" - }, { - "name": "ohos.permission.INTERNET" - }, - { - "name": "ohos.permission.GET_WIFI_INFO", - }, { "name": "ohos.permission.DISTRIBUTED_DATASYNC", }, diff --git a/material/ac/8da748c94a6f4d36b142a3edc090dc40 b/material/ac/8da748c94a6f4d36b142a3edc090dc40 new file mode 100644 index 0000000..9c754d8 --- /dev/null +++ b/material/ac/8da748c94a6f4d36b142a3edc090dc40 @@ -0,0 +1 @@ +2\&3 ¢ \ No newline at end of file diff --git a/material/ce/bc943325cea34e90a617b11ef6887551 b/material/ce/bc943325cea34e90a617b11ef6887551 new file mode 100644 index 0000000..e193b69 Binary files /dev/null and b/material/ce/bc943325cea34e90a617b11ef6887551 differ diff --git a/material/fd/0/dfc5f63f37634c3facdbae6dba056f8c b/material/fd/0/dfc5f63f37634c3facdbae6dba056f8c new file mode 100644 index 0000000..f715371 --- /dev/null +++ b/material/fd/0/dfc5f63f37634c3facdbae6dba056f8c @@ -0,0 +1 @@ +T& cFw*'a \ No newline at end of file diff --git a/material/fd/1/3ddea8591dce46e2a2417929f4c58457 b/material/fd/1/3ddea8591dce46e2a2417929f4c58457 new file mode 100644 index 0000000..f7ce4d6 --- /dev/null +++ b/material/fd/1/3ddea8591dce46e2a2417929f4c58457 @@ -0,0 +1 @@ +\P,{U" \ No newline at end of file diff --git a/material/fd/2/184135aff5914321aece4570bbb31ed6 b/material/fd/2/184135aff5914321aece4570bbb31ed6 new file mode 100644 index 0000000..d965bd3 --- /dev/null +++ b/material/fd/2/184135aff5914321aece4570bbb31ed6 @@ -0,0 +1 @@ +7ɓv( \ No newline at end of file