feat: finish sheetBind

This commit is contained in:
🍒cheliangzhao⭐ 2023-11-22 18:34:30 +08:00
commit 1936196b00
47 changed files with 1094 additions and 0 deletions

11
.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
/node_modules
/oh_modules
/local.properties
/.idea
**/build
/.hvigor
.cxx
/.clangd
/.clang-format
/.clang-tidy
**/.test

10
AppScope/app.json5 Normal file
View File

@ -0,0 +1,10 @@
{
"app": {
"bundleName": "com.example.panel",
"vendor": "example",
"versionCode": 1000000,
"versionName": "1.0.0",
"icon": "$media:app_icon",
"label": "$string:app_name"
}
}

View File

@ -0,0 +1,8 @@
{
"string": [
{
"name": "app_name",
"value": "Panel"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

50
build-profile.json5 Normal file
View File

@ -0,0 +1,50 @@
{
"app": {
"products": [
{
"name": "default",
"signingConfig": "default",
"compileSdkVersion": "4.0.0(10)",
"compatibleSdkVersion": "4.0.0(10)",
"runtimeOS": "HarmonyOS"
}
],
"buildModeSet": [
{
"name": "debug"
},
{
"name": "release"
}
],
"signingConfigs": [
{
"name": "default",
"type": "HarmonyOS",
"material": {
"certpath": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony-demo-panel_com.example.panel_70086000144137060.cer",
"storePassword": "0000001BDA1568E6FC7F9D67F9116B46BAF3635A180A9B0F775F92EA9056F74C573805DE767B74781E8246",
"keyAlias": "debugKey",
"keyPassword": "0000001B1716A04F4856291436BCE42F79B026527EA9427CAC968CAD6672539EA36D30AB2F3D853CE0F1BB",
"profile": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony-demo-panel_com.example.panel_70086000144137060.p7b",
"signAlg": "SHA256withECDSA",
"storeFile": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony-demo-panel_com.example.panel_70086000144137060.p12"
}
}
]
},
"modules": [
{
"name": "entry",
"srcPath": "./entry",
"targets": [
{
"name": "default",
"applyToProducts": [
"default"
]
}
]
}
]
}

BIN
dependencies/hvigor-3.0.4-s.tgz vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
dependencies/rollup.tgz vendored Normal file

Binary file not shown.

6
entry/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
/node_modules
/oh_modules
/.preview
/build
/.cxx
/.test

31
entry/build-profile.json5 Normal file
View File

@ -0,0 +1,31 @@
{
"apiType": "stageMode",
"buildOption": {
"arkOptions": {
// "apPath": "./modules.ap" /* Profile used for profile-guided optimization (PGO), a compiler optimization technique to improve app runtime performance. */
}
},
"buildOptionSet": [
{
"name": "release",
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true,
"files": [
"./obfuscation-rules.txt"
]
}
}
}
},
],
"targets": [
{
"name": "default"
},
{
"name": "ohosTest",
}
]
}

6
entry/hvigorfile.ts Normal file
View File

@ -0,0 +1,6 @@
import { hapTasks } from '@ohos/hvigor-ohos-plugin';
export default {
system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
}

View File

@ -0,0 +1,18 @@
# Define project specific obfuscation rules here.
# You can include the obfuscation configuration files in the current module's build-profile.json5.
#
# For more details, see
# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md
# Obfuscation options:
# -disable-obfuscation: disable all obfuscations
# -enable-property-obfuscation: obfuscate the property names
# -enable-toplevel-obfuscation: obfuscate the names in the global scope
# -compact: remove unnecessary blank spaces and all line feeds
# -remove-log: remove all console.* statements
# -print-namecache: print the name cache that contains the mapping from the old names to new names
# -apply-namecache: reuse the given cache file
# Keep options:
# -keep-property-name: specifies property names that you want to keep
# -keep-global-name: specifies names that you want to keep in the global scope

10
entry/oh-package.json5 Normal file
View File

@ -0,0 +1,10 @@
{
"license": "",
"devDependencies": {},
"author": "",
"name": "entry",
"description": "Please describe the basic information.",
"main": "",
"version": "1.0.0",
"dependencies": {}
}

View File

@ -0,0 +1,59 @@
/**
* 定制可上下滑动的panel
*
* @param show: 控制面板显示
* @param contentView: 面板内部显示的组件
* @param defaultHeight: 默认高度,取值范围为[0, 1000]
* @param showDragBar: 是否显示顶部bar
* @param onClose: 关闭时的回调函数,可选
* @author cheliangzhao
*/
@Component
export struct CustomPanel {
private TAG: string = 'CustomPanel'
@Prop show: boolean
@BuilderParam contentView: () => void
@Prop defaultHeight: number = 800
@Prop showDragBar: boolean = false;
onClose: () => void = () => {
}
aboutToAppear() {
console.info(this.TAG, 'aboutToAppear')
}
closePanel() {
this.show = false;
if (this.onClose) this.onClose();
}
aboutToDisappear() {
console.info(this.TAG, 'aboutToDisAppear')
this.closePanel()
}
@Builder
innerView() {
this.contentView()
}
build() {
Panel(this.show) {
this.innerView();
}
.type(PanelType.Foldable)
.mode(PanelMode.Half)
.dragBar(this.showDragBar) // 默认关闭
.halfHeight(this.defaultHeight) // 默认一半
// .showCloseIcon(true) // 显示关闭图标
// .backgroundMask('#B3111317') // mask color
.position({ x: 0, y: 0 })
// .padding({ top: 30 }) // TODO: 根据状态栏高度设置
.borderRadius({ topLeft: 0, topRight: 0 })
.onChange((width: number, height: number, mode: PanelMode) => {
if (mode == 0) {
this.closePanel() // 下滑关闭
}
})
}
}

View File

@ -0,0 +1,27 @@
@CustomDialog
export struct MyDialog {
private TAG: string = "SlideDialog"
private controller: CustomDialogController
@BuilderParam innerView: () => void = this.defaultBuilder
@Builder
defaultBuilder() {
}
aboutToAppear() {
console.info(this.TAG, " aboutToAppear")
}
aboutToDisappear() {
console.info(this.TAG, " aboutToDisappear")
this.controller.close()
}
build() {
Column({ space: 10 }) {
this.innerView()
}
.width('100%')
.expandSafeArea([SafeAreaType.SYSTEM, SafeAreaType.KEYBOARD])
}
}

View File

@ -0,0 +1,43 @@
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import hilog from '@ohos.hilog';
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
import window from '@ohos.window';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
}
onDestroy() {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
}
onWindowStageCreate(windowStage: window.WindowStage) {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
});
}
onWindowStageDestroy() {
// Main window is destroyed, release UI related resources
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}
onForeground() {
// Ability has brought to foreground
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
}
onBackground() {
// Ability has back to background
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
}
}

View File

@ -0,0 +1,181 @@
// 下滑弹窗测试
import { CustomPanel } from '../components/CustomPanel';
import curves from '@ohos.curves';
import { InnerView } from '../views/InnerView'
import { SideBar } from '../views/SideBar';
import { MyDialog } from '../components/SlideDialog';
interface IControlValue {
beginX: number;
endX: number;
maxMoveRate: number;
swipeDirection: number;
leftMoveDistance: number;
}
@Observed
class UIState {
showPanel: boolean = false;
// 模态转场控制变量
isPresent: boolean = false;
sheetIsPresent: boolean = false;
}
// 1custom panel
// 2模态转场
@Preview
@Entry
@Component
struct Index {
private TAG: string = 'IndexEntry'
private defaultWidth: number = 350
@State message: string = "This a Template Project"
@State uiState: UIState = new UIState()
private controller = new CustomDialogController({
builder: MyDialog({ innerView: this.InnerView }),
alignment: DialogAlignment.Bottom,
// offset: { dx: 0, dy: 0 },
// customStyle: true,
})
// sidebar控制变量
controlValue: IControlValue = {
beginX: 0,
endX: 0,
maxMoveRate: 0.12,
swipeDirection: 0, // 0 is left, 1 is right
leftMoveDistance: 0,
}
// @State contentWidth: number | string = this.defaultWidth;
// @State marginLeft: number = 0;
@Builder
InnerView() {
Row() {
InnerView()
}
}
onClose() {
this.uiState.isPresent = false;
}
// @Builder
// sideBar_origin() {
// Column() {
// InnerView()
// }
// .margin({ left: -this.marginLeft })
// .width(this.contentWidth)
// .height('100%')
// .transition( // 通过转场动画实现出现消失转场动画效果transition需要加在builder下的第一个组件
// TransitionEffect.translate({ x: '-' + this.contentWidth, y: 0, z: 0 })
// .animation({ curve: curves.springMotion(0.6, 0.8) })
// )
// .onTouch(event => {
// // 按下赋初始值
// if (event.type === TouchType.Down) {
// this.controlValue.beginX = event.touches[0].displayX;
// this.controlValue.leftMoveDistance = 0;
// }
// // 移动改变移动宽度
// if (event.type === TouchType.Move) {
// this.controlValue.endX = event.touches[0].displayX; // 手指停止的位置
// const moveDistance = this.controlValue.beginX - this.controlValue.endX; // 滑动的水平距离
//
// // 判断水平滑动方向
// if (this.controlValue.leftMoveDistance > 0) {
// this.controlValue.swipeDirection = 0;
// } else {
// this.controlValue.swipeDirection = 1;
// }
//
// // 更新
// this.marginLeft = (this.marginLeft + moveDistance) > 0 ? (this.marginLeft + moveDistance) : 0;
//
// this.controlValue.beginX = this.controlValue.endX;
//
// this.controlValue.leftMoveDistance += moveDistance
// }
//
// if (event.type === TouchType.Up) {
// console.log(this.TAG, 'TouchType up' + this.controlValue.leftMoveDistance);
// if (this.controlValue.leftMoveDistance > this.controlValue.maxMoveRate * +this.defaultWidth) {
// this.isPresent = false;
// }
// this.marginLeft = 0;
// }
// })
// .gesture(
// SwipeGesture({ direction: SwipeDirection.Horizontal })
// .onAction((event?: GestureEvent) => {
// if (event && this.controlValue.swipeDirection == 0) {
// this.isPresent = false;
// this.marginLeft = 0;
// }
// })
// ) // 快速滑动关闭
// }
@Builder
sideBarComponent() {
SideBar({
contentView: (): void => this.InnerView(),
contentWidth: this.defaultWidth,
onClose: () => this.uiState.isPresent = false,
})
.transition(// 通过转场动画实现出现消失转场动画效果transition需要加在builder下的第一个组件
TransitionEffect.translate({ x: '-' + this.defaultWidth, y: 0, z: 0 })
.animation({ curve: curves.springMotion(0.6, 0.8) })
)
}
build() {
Column() {
Button('open panel')
.onClick(() => this.uiState.showPanel = true);
Button('全屏模态转场')// 通过选定的模态接口绑定模态展示界面ModalTransition是内置的ContentCover转场动画类型这里选择None代表系统不加默认动画
// @ts-ignore
.bindContentCover($$this.uiState.isPresent, this.sideBarComponent, ModalTransition.NONE)
.onClick(() => {
this.uiState.isPresent = true;
})
Button('半模态转场')//
// @ts-ignore
.bindSheet($$this.uiState.sheetIsPresent, this.InnerView, {
dragBar: true,
height: SheetSize.MEDIUM,
maskColor: Color.Gray,
onAppear: () => {
console.info(this.TAG, ':bindSheet onAppear')
},
onDisappear: () => {
console.info(this.TAG, ':bindSheet onDisappear')
this.uiState.sheetIsPresent = false
}
})
.onClick(() => {
this.uiState.sheetIsPresent = true
})
Button('Slide Dialog')
.onClick(() => {
this.controller.open()
})
CustomPanel({
contentView: this.InnerView,
show: this.uiState.showPanel,
// defaultHeight: 1000,
showDragBar: true,
onClose: () => this.uiState.showPanel = false
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.SpaceEvenly)
.expandSafeArea([SafeAreaType.SYSTEM, SafeAreaType.KEYBOARD])
}
}

View File

@ -0,0 +1,31 @@
// TODO: 请扫点距离返回动画
@Preview
@Component
export struct InnerView {
@State message: string = "This is a Inner View";
build() {
Column() {
Search()
// Text(this.message).margin({ top: 10, bottom: 10 })
List() {
ForEach(Array(10).fill(0).map((_: number, idx) => idx + 1), (item: number) => {
ListItem() {
Text(`item: ${item}`)
.width('100%')
.backgroundColor('#FFFFFF')
.height(60)
.margin({ bottom: 10 })
.borderRadius(8)
.padding({ left: 16, right: 16 })
}
})
}
.scrollBar(BarState.Off)
.layoutWeight(1)
}
.height('100%')
.padding({ left: 16, right: 16 })
.backgroundColor('#E6E8EC')
}
}

View File

@ -0,0 +1,82 @@
interface IControllerValue {
beginX: number;
endX: number;
maxMoveRate: number;
swipeDirection: number;
leftMoveDistance: number;
}
@Component
export struct SideBar {
private TAG: string = 'Sidebar';
private defaultWidth: number = 350
@BuilderParam contentView: () => void
// 模态转场控制变量
onClose: () => void = () => {
}
@Prop contentWidth: number | string = this.defaultWidth;
@State marginLeft: number = 0;
// sidebar控制变量
controlValue: IControllerValue = {
beginX: 0,
endX: 0,
maxMoveRate: 0.12,
swipeDirection: 0, // 0 is left, 1 is right
leftMoveDistance: 0,
}
aboutToDisappear() {
this.onClose()
}
build() {
Column() {
this.contentView()
}
.margin({ left: -this.marginLeft })
.width(this.contentWidth)
.height('100%')
.onTouch(event => {
// 按下赋初始值
if (event.type === TouchType.Down) {
this.controlValue.beginX = event.touches[0].displayX;
this.controlValue.leftMoveDistance = 0;
}
// 移动改变宽度
if (event.type === TouchType.Move) {
this.controlValue.endX = event.touches[0].displayX; // 手指停止的位置
const moveDistance = this.controlValue.beginX - this.controlValue.endX; // 滑动的水平距离
// 判断水平滑动方向
if (this.controlValue.leftMoveDistance > 0) {
this.controlValue.swipeDirection = 0;
} else {
this.controlValue.swipeDirection = 1;
}
// 更新
this.marginLeft = (this.marginLeft + moveDistance) > 0 ? (this.marginLeft + moveDistance) : 0;
this.controlValue.beginX = this.controlValue.endX;
this.controlValue.leftMoveDistance += moveDistance
}
// 手指抬起判断是否关闭
if (event.type === TouchType.Up) {
console.log(this.TAG, 'TouchType up' + this.controlValue.leftMoveDistance);
if (this.controlValue.leftMoveDistance > this.controlValue.maxMoveRate * +this.defaultWidth) {
this.onClose()
}
this.marginLeft = 0;
}
})
.gesture(
SwipeGesture({ direction: SwipeDirection.Horizontal })
.onAction((event?: GestureEvent) => {
if (event && this.controlValue.swipeDirection == 0) {
this.onClose()
this.marginLeft = 0;
}
})
) // 快速滑动关闭
}
}

View File

@ -0,0 +1,38 @@
{
"module": {
"name": "entry",
"type": "entry",
"description": "$string:module_desc",
"mainElement": "EntryAbility",
"deviceTypes": [
"phone",
"tablet",
"2in1"
],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:main_pages",
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:icon",
"label": "$string:app_name",
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
]
}
]
}
}

View File

@ -0,0 +1,8 @@
{
"color": [
{
"name": "start_window_background",
"value": "#FFFFFF"
}
]
}

View File

@ -0,0 +1,16 @@
{
"string": [
{
"name": "module_desc",
"value": "module description"
},
{
"name": "EntryAbility_desc",
"value": "description"
},
{
"name": "EntryAbility_label",
"value": "label"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,5 @@
{
"src": [
"pages/Index"
]
}

View File

@ -0,0 +1,16 @@
{
"string": [
{
"name": "module_desc",
"value": "module description"
},
{
"name": "EntryAbility_desc",
"value": "description"
},
{
"name": "EntryAbility_label",
"value": "label"
}
]
}

View File

@ -0,0 +1,16 @@
{
"string": [
{
"name": "module_desc",
"value": "模块描述"
},
{
"name": "EntryAbility_desc",
"value": "description"
},
{
"name": "EntryAbility_label",
"value": "label"
}
]
}

View File

@ -0,0 +1,35 @@
import hilog from '@ohos.hilog';
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
export default function abilityTest() {
describe('ActsAbilityTest', () => {
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
beforeAll(() => {
// Presets an action, which is performed only once before all test cases of the test suite start.
// This API supports only one parameter: preset action function.
})
beforeEach(() => {
// Presets an action, which is performed before each unit test case starts.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: preset action function.
})
afterEach(() => {
// Presets a clear action, which is performed after each unit test case ends.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: clear action function.
})
afterAll(() => {
// Presets a clear action, which is performed after all test cases of the test suite end.
// This API supports only one parameter: clear action function.
})
it('assertContain', 0, () => {
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
hilog.info(0x0000, 'testTag', '%{public}s', 'it begin');
let a = 'abc';
let b = 'b';
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
expect(a).assertContain(b);
expect(a).assertEqual(a);
})
})
}

View File

@ -0,0 +1,5 @@
import abilityTest from './Ability.test';
export default function testsuite() {
abilityTest();
}

View File

@ -0,0 +1,50 @@
import UIAbility from '@ohos.app.ability.UIAbility';
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
import hilog from '@ohos.hilog';
import { Hypium } from '@ohos/hypium';
import testsuite from '../test/List.test';
import window from '@ohos.window';
import Want from '@ohos.app.ability.Want';
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
export default class TestAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate');
hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? '');
hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:' + JSON.stringify(launchParam) ?? '');
let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator;
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs;
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments();
hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!');
Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite);
}
onDestroy() {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy');
}
onWindowStageCreate(windowStage: window.WindowStage) {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate');
windowStage.loadContent('testability/pages/Index', (err, data) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s',
JSON.stringify(data) ?? '');
});
}
onWindowStageDestroy() {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy');
}
onForeground() {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground');
}
onBackground() {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground');
}
}

View File

@ -0,0 +1,17 @@
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%')
}
.height('100%')
}
}

View File

@ -0,0 +1,47 @@
import hilog from '@ohos.hilog';
import TestRunner from '@ohos.application.testRunner';
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
import Want from '@ohos.app.ability.Want';
let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator | undefined = undefined
let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs | undefined = undefined
async function onAbilityCreateCallback() {
hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback');
}
async function addAbilityMonitorCallback(err : Error) {
hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? '');
}
export default class OpenHarmonyTestRunner implements TestRunner {
constructor() {
}
onPrepare() {
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare ');
}
async onRun() {
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run');
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments()
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
const bundleName = abilityDelegatorArguments.bundleName;
const testAbilityName = 'TestAbility';
let lMonitor: AbilityDelegatorRegistry.AbilityMonitor = {
abilityName: testAbilityName,
onAbilityCreate: onAbilityCreateCallback,
};
abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback)
const want: Want = {
bundleName: bundleName,
abilityName: testAbilityName
};
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
abilityDelegator.startAbility(want, (err, data) => {
hilog.info(0x0000, 'testTag', 'startAbility : err : %{public}s', JSON.stringify(err) ?? '');
hilog.info(0x0000, 'testTag', 'startAbility : data : %{public}s',JSON.stringify(data) ?? '');
})
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end');
}
}

View File

@ -0,0 +1,38 @@
{
"module": {
"name": "entry_test",
"type": "feature",
"description": "$string:module_test_desc",
"mainElement": "TestAbility",
"deviceTypes": [
"phone",
"tablet",
"2in1"
],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:test_pages",
"abilities": [
{
"name": "TestAbility",
"srcEntry": "./ets/testability/TestAbility.ets",
"description": "$string:TestAbility_desc",
"icon": "$media:icon",
"label": "$string:TestAbility_label",
"exported": true,
"startWindowIcon": "$media:icon",
"startWindowBackground": "$color:start_window_background",
"skills": [
{
"actions": [
"action.system.home"
],
"entities": [
"entity.system.home"
]
}
]
}
]
}
}

View File

@ -0,0 +1,8 @@
{
"color": [
{
"name": "start_window_background",
"value": "#FFFFFF"
}
]
}

View File

@ -0,0 +1,16 @@
{
"string": [
{
"name": "module_test_desc",
"value": "test ability description"
},
{
"name": "TestAbility_desc",
"value": "the test ability"
},
{
"name": "TestAbility_label",
"value": "test label"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -0,0 +1,5 @@
{
"src": [
"testability/pages/Index"
]
}

View File

@ -0,0 +1,5 @@
import localUnitTest from './LocalUnit.test';
export default function testsuite() {
localUnitTest();
}

View File

@ -0,0 +1,33 @@
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
export default function localUnitTest() {
describe('localUnitTest',() => {
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
beforeAll(() => {
// Presets an action, which is performed only once before all test cases of the test suite start.
// This API supports only one parameter: preset action function.
});
beforeEach(() => {
// Presets an action, which is performed before each unit test case starts.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: preset action function.
});
afterEach(() => {
// Presets a clear action, which is performed after each unit test case ends.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: clear action function.
});
afterAll(() => {
// Presets a clear action, which is performed after all test cases of the test suite end.
// This API supports only one parameter: clear action function.
});
it('assertContain', 0, () => {
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
let a = 'abc';
let b = 'b';
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
expect(a).assertContain(b);
expect(a).assertEqual(a);
});
});
}

View File

@ -0,0 +1,19 @@
{
"hvigorVersion": "file:../dependencies/hvigor-3.0.4-s.tgz",
"dependencies": {
"@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-3.0.4-s.tgz",
"rollup": "file:../dependencies/rollup.tgz"
},
"execution": {
// "daemon": true, /* Enable daemon compilation. Default: true */
// "incremental": true, /* Enable incremental compilation. Default: true */
// "parallel": true, /* Enable parallel compilation. Default: true */
// "typeCheck": false, /* Enable typeCheck. Default: false */
},
"logging": {
// "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */
},
"debugging": {
// "stacktrace": false /* Disable stacktrace compilation. Default: false */
}
}

1
hvigor/hvigor-wrapper.js Normal file

File diff suppressed because one or more lines are too long

6
hvigorfile.ts Normal file
View File

@ -0,0 +1,6 @@
import { appTasks } from '@ohos/hvigor-ohos-plugin';
export default {
system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
}

48
hvigorw Normal file
View File

@ -0,0 +1,48 @@
#!/bin/bash
# ----------------------------------------------------------------------------
# Hvigor startup script, version 1.0.0
#
# Required ENV vars:
# ------------------
# NODE_HOME - location of a Node home dir
# or
# Add /usr/local/nodejs/bin to the PATH environment variable
# ----------------------------------------------------------------------------
HVIGOR_APP_HOME="`pwd -P`"
HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js
warn() {
echo ""
echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m"
}
error() {
echo ""
echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m"
}
fail() {
error "$@"
exit 1
}
# Determine node to start hvigor wrapper script
if [ -n "${NODE_HOME}" ];then
EXECUTABLE_NODE="${NODE_HOME}/bin/node"
if [ ! -x "$EXECUTABLE_NODE" ];then
fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed"
fi
else
EXECUTABLE_NODE="node"
which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path"
fi
# Check hvigor wrapper script
if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then
fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}"
fi
# start hvigor-wrapper script
exec "${EXECUTABLE_NODE}" \
"${HVIGOR_WRAPPER_SCRIPT}" "$@"

64
hvigorw.bat Normal file
View File

@ -0,0 +1,64 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Hvigor startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js
set NODE_EXE=node.exe
goto start
:start
@rem Find node.exe
if defined NODE_HOME goto findNodeFromNodeHome
%NODE_EXE% --version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH.
echo.
echo Please set the NODE_HOME variable in your environment to match the
echo location of your NodeJs installation.
goto fail
:findNodeFromNodeHome
set NODE_HOME=%NODE_HOME:"=%
set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE%
if exist "%NODE_EXE_PATH%" goto execute
echo.
echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH.
echo.
echo Please set the NODE_HOME variable in your environment to match the
echo location of your NodeJs installation.
goto fail
:execute
@rem Execute hvigor
"%NODE_EXE%" "%WRAPPER_MODULE_PATH%" %*
if "%ERRORLEVEL%" == "0" goto hvigorwEnd
:fail
exit /b 1
:hvigorwEnd
if "%OS%" == "Windows_NT" endlocal
:end

13
oh-package-lock.json5 Normal file
View File

@ -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=="
}
}
}

12
oh-package.json5 Normal file
View File

@ -0,0 +1,12 @@
{
"license": "",
"devDependencies": {
"@ohos/hypium": "1.0.6"
},
"author": "",
"name": "harmony-demo-panel",
"description": "Please describe the basic information.",
"main": "",
"version": "1.0.0",
"dependencies": {}
}