diff --git a/code/ConcurrencyDemo/.gitignore b/code/ConcurrencyDemo/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/code/ConcurrencyDemo/.gitignore @@ -0,0 +1,12 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +/.appanalyzer \ No newline at end of file diff --git a/code/ConcurrencyDemo/AppScope/app.json5 b/code/ConcurrencyDemo/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..27c73b40ae822e57166a857d945fdd5fea11bbde --- /dev/null +++ b/code/ConcurrencyDemo/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.helloworld", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/code/ConcurrencyDemo/AppScope/resources/base/element/string.json b/code/ConcurrencyDemo/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..0f45ffda7c2ba8045db510d54fc1624d37afcf40 --- /dev/null +++ b/code/ConcurrencyDemo/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "HelloWorld" + } + ] +} diff --git a/code/ConcurrencyDemo/AppScope/resources/base/media/app_icon.png b/code/ConcurrencyDemo/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a39445dc87828b76fed6d2ec470dd455c45319e3 Binary files /dev/null and b/code/ConcurrencyDemo/AppScope/resources/base/media/app_icon.png differ diff --git a/code/ConcurrencyDemo/build-profile.json5 b/code/ConcurrencyDemo/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..787976bf07b4787a3c2b4020b6ae4dd9377364c1 --- /dev/null +++ b/code/ConcurrencyDemo/build-profile.json5 @@ -0,0 +1,42 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": 14, + "compileSdkVersion": 17, + "runtimeOS": "OpenHarmony", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/code/ConcurrencyDemo/code-linter.json5 b/code/ConcurrencyDemo/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..073990fa45394e1f8e85d85418ee60a8953f9b99 --- /dev/null +++ b/code/ConcurrencyDemo/code-linter.json5 @@ -0,0 +1,32 @@ +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + "@security/no-unsafe-aes": "error", + "@security/no-unsafe-hash": "error", + "@security/no-unsafe-mac": "warn", + "@security/no-unsafe-dh": "error", + "@security/no-unsafe-dsa": "error", + "@security/no-unsafe-ecdsa": "error", + "@security/no-unsafe-rsa-encrypt": "error", + "@security/no-unsafe-rsa-sign": "error", + "@security/no-unsafe-rsa-key": "error", + "@security/no-unsafe-dsa-key": "error", + "@security/no-unsafe-dh-key": "error", + "@security/no-unsafe-3des": "error" + } +} \ No newline at end of file diff --git a/code/ConcurrencyDemo/entry/.gitignore b/code/ConcurrencyDemo/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/code/ConcurrencyDemo/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/code/ConcurrencyDemo/entry/build-profile.json5 b/code/ConcurrencyDemo/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..ba86f7fda88cdd2113eaaca2639a93068f5a6096 --- /dev/null +++ b/code/ConcurrencyDemo/entry/build-profile.json5 @@ -0,0 +1,29 @@ +{ + "apiType": "stageMode", + "arkTSVersion": "1.2", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/code/ConcurrencyDemo/entry/hvigorfile.ts b/code/ConcurrencyDemo/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/code/ConcurrencyDemo/entry/hvigorfile.ts @@ -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. */ +} diff --git a/code/ConcurrencyDemo/entry/obfuscation-rules.txt b/code/ConcurrencyDemo/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/code/ConcurrencyDemo/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# 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://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# 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 + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/code/ConcurrencyDemo/entry/oh-package.json5 b/code/ConcurrencyDemo/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..2959d78c50285f912adb2cdff9f613df9a503b44 --- /dev/null +++ b/code/ConcurrencyDemo/entry/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": {} +} + diff --git a/code/ConcurrencyDemo/entry/src/main/ets/entryability/EntryAbility.ets b/code/ConcurrencyDemo/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..964c580b66c3d336b49258e9941f1be0032127eb --- /dev/null +++ b/code/ConcurrencyDemo/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,28 @@ +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import Want from '@ohos.app.ability.Want'; +import window from '@ohos.window'; +import type { BusinessError } from '@ohos.base' +import hilog from '@ohos.hilog' + +class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + hilog.info(0x0000, 'testTag', 'EntryAbility onCreate'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + hilog.info(0x0000, 'testTag', 'EntryAbility onWindowStageCreate'); + try { + windowStage.loadContent('pages/Index', (err: BusinessError): void => { + hilog.info(0x0000, 'testTag', 'loadContent entering'); + if (err.code) { + hilog.info(0x0000, 'testTag', 'loadContent error'); + return; + } + hilog.info(0x0000, 'testTag', 'loadContent ok'); + }); + } catch (e: Error) { + hilog.info(0x0000, 'testTag', 'loadContent catch error:-----------' + e.message); + } + } +} \ No newline at end of file diff --git a/code/ConcurrencyDemo/entry/src/main/ets/pages/Index.ets b/code/ConcurrencyDemo/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..68bfd058974d2d3f510d3cc53adde830113f3881 --- /dev/null +++ b/code/ConcurrencyDemo/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,37 @@ +import { Text } from "@koalaui.arkts-arkui.Text" +import { Column } from "@koalaui.arkts-arkui.Column" +import { Button } from "@koalaui.arkts-arkui.Button" +import { Component } from "@koalaui.arkts-arkui.Common" +import { UserView, UserViewBuilder } from "@koalaui.arkts-arkui.UserView" +import { __memo_context_type, __memo_id_type } from "@ohos.arkui.StateManagement.runtime" +import { memo } from "@ohos.arkui.StateManagement.runtime" +import hilog from '@ohos.hilog' + +@Component +struct MyStateSample { + build() { + Column() { + Text("Hello World!") + Button('change') + } + } +} + +export class ComExampleTrivialApplication extends UserView { + getBuilder(): UserViewBuilder { + hilog.info(0x0000, 'testTag', 'ComExampleTrivialApplication'); + let wrapper = (__memo_context: __memo_context_type, __memo_id: __memo_id_type) => { + hilog.info(0x0000, 'testTag', 'MyStateSample.instantiateImpl'); + MyStateSample.instantiateImpl( + // __memo_context, + // ((__memo_id) + (21211165)), + undefined, + (): MyStateSample => new MyStateSample(), + {} as __Options_MyStateSample, + undefined + ) + } + hilog.info(0x0000, 'testTag', 'getBuilder.end'); + return wrapper + } +} \ No newline at end of file diff --git a/code/ConcurrencyDemo/entry/src/main/module.json5 b/code/ConcurrencyDemo/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..b73e4682583084e417d967d9b6d273f95df7fea3 --- /dev/null +++ b/code/ConcurrencyDemo/entry/src/main/module.json5 @@ -0,0 +1,37 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "default", + "tablet", + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/code/ConcurrencyDemo/entry/src/main/resources/base/element/color.json b/code/ConcurrencyDemo/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..d66f9a7d4ac61fb8d215239ab3620b7bcd77bf33 --- /dev/null +++ b/code/ConcurrencyDemo/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/code/ConcurrencyDemo/entry/src/main/resources/base/element/float.json b/code/ConcurrencyDemo/entry/src/main/resources/base/element/float.json new file mode 100644 index 0000000000000000000000000000000000000000..a8a5d404dcd8b0466194afc3aa25d90a8a327470 --- /dev/null +++ b/code/ConcurrencyDemo/entry/src/main/resources/base/element/float.json @@ -0,0 +1,8 @@ +{ + "float": [ + { + "name": "page_text_font_size", + "value": "50fp" + } + ] +} diff --git a/code/ConcurrencyDemo/entry/src/main/resources/base/element/string.json b/code/ConcurrencyDemo/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/code/ConcurrencyDemo/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/code/ConcurrencyDemo/entry/src/main/resources/base/media/background.png b/code/ConcurrencyDemo/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..923f2b3f27e915d6871871deea0420eb45ce102f Binary files /dev/null and b/code/ConcurrencyDemo/entry/src/main/resources/base/media/background.png differ diff --git a/code/ConcurrencyDemo/entry/src/main/resources/base/media/foreground.png b/code/ConcurrencyDemo/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..97014d3e10e5ff511409c378cd4255713aecd85f Binary files /dev/null and b/code/ConcurrencyDemo/entry/src/main/resources/base/media/foreground.png differ diff --git a/code/ConcurrencyDemo/entry/src/main/resources/base/media/layered_image.json b/code/ConcurrencyDemo/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/code/ConcurrencyDemo/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/code/ConcurrencyDemo/entry/src/main/resources/base/media/startIcon.png b/code/ConcurrencyDemo/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/code/ConcurrencyDemo/entry/src/main/resources/base/media/startIcon.png differ diff --git a/code/ConcurrencyDemo/entry/src/main/resources/base/profile/backup_config.json b/code/ConcurrencyDemo/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..d742c2f96e7dd0f406f499941f3147345e998f95 --- /dev/null +++ b/code/ConcurrencyDemo/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/code/ConcurrencyDemo/entry/src/main/resources/base/profile/main_pages.json b/code/ConcurrencyDemo/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/code/ConcurrencyDemo/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/code/ConcurrencyDemo/entry/src/main/resources/dark/element/color.json b/code/ConcurrencyDemo/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..438d5bc43bb23c59c210d586b96635a72da5b64a --- /dev/null +++ b/code/ConcurrencyDemo/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/code/ConcurrencyDemo/hvigor/hvigor-config.json5 b/code/ConcurrencyDemo/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..3d2636d32ef0cad1df3e8dc11f691bb9dc870344 --- /dev/null +++ b/code/ConcurrencyDemo/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.2", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/code/ConcurrencyDemo/hvigorfile.ts b/code/ConcurrencyDemo/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/code/ConcurrencyDemo/hvigorfile.ts @@ -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. */ +} diff --git a/code/ConcurrencyDemo/oh-package.json5 b/code/ConcurrencyDemo/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..78bf3d8322745df4174f5ac23de6f4da67182012 --- /dev/null +++ b/code/ConcurrencyDemo/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.2", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.21", + "@ohos/hamock": "1.0.0" + } +} diff --git a/code/HelloWorld/entry/src/main/ets/entryability/EntryAbility.ets b/code/HelloWorld/entry/src/main/ets/entryability/EntryAbility.ets index 964c580b66c3d336b49258e9941f1be0032127eb..c39252a7c3c5741ef5c909cb8ae03915010d3f92 100644 --- a/code/HelloWorld/entry/src/main/ets/entryability/EntryAbility.ets +++ b/code/HelloWorld/entry/src/main/ets/entryability/EntryAbility.ets @@ -5,9 +5,181 @@ import window from '@ohos.window'; import type { BusinessError } from '@ohos.base' import hilog from '@ohos.hilog' +type Test = () => BasicTest + +class FuncTest { + public static setTimeoutTest() : BasicTest { + let globalTest = new BasicTest(3, 'setTimeoutTest'); + let delay = 100; + globalTest!.checkpoint(0); + let start = Date.now(); + setTimeout((): void => { + let spentTime = Date.now() - start + 1; + if (spentTime < delay) { + globalTest!.fail("The callback is called after " + spentTime + "ms. Expected to be called after " + delay + "ms at least."); + } + globalTest!.checkpoint(2); + }, delay); + globalTest!.checkpoint(1); + return globalTest + } + + public static clearTimeoutTest() : BasicTest { + let globalTest = new BasicTest(2, 'clearTimeoutTest'); + globalTest!.checkpoint(0); + let timerId = setTimeout((): void => { + globalTest!.fail("The callback should not be called."); + }, 0); + clearTimeout(timerId); + globalTest!.checkpoint(1); + return globalTest + } + + public static promiseResolveTest() : BasicTest { + let globalTest = new BasicTest(5, 'promiseResolveTest'); + globalTest!.checkpoint(0); + let p = new Promise((res: (v:int) => void, rej: (v:int) => void) : void => { + globalTest!.checkpoint(1); + setTimeout(() => { + globalTest!.checkpoint(3); + res(0) + }, 10) + }) + + p.then((v : int) : void => { + if(v != 0) globalTest!.fail("The resolve value should be 0, but got " + v + "!") + globalTest!.checkpoint(4); + }, (e: NullishType) : void => { + globalTest!.fail("The promise should not be rejected!") + }).catch((e: NullishType) : void => { + globalTest!.fail("The promise should not be rejected!") + }) + globalTest!.checkpoint(2); + return globalTest + } + + public static promiseRejectTest() : BasicTest { + let globalTest = new BasicTest(5, 'promiseRejectTest'); + globalTest!.checkpoint(0); + let p = new Promise((res: (v:int) => void, rej: (v:Error) => void) : void => { + globalTest!.checkpoint(1); + setTimeout(() => { + globalTest!.checkpoint(3); + rej(new Error("reject")) + }, 10) + }) + + p.then((v : int) : void => { + globalTest!.fail("The resolve value should not be rejected!") + }).catch((e: Error) : void => { + if(e.message != 'reject') globalTest!.fail("The reject reason should be \"rejected\"!") + globalTest!.checkpoint(4); + }) + globalTest!.checkpoint(2); + return globalTest + } + + public static taskpoolExecuteTest() : BasicTest { + let globalTest = new BasicTest(3, 'taskpoolExecuteTest'); + globalTest!.checkpoint(0); + let p = taskpool.execute(() : int => { + globalTest!.checkpoint(1); + return 0 + }) + p.then((v: NullishType) : void => { + globalTest!.checkpoint(2); + let res = v as int + if(res != 0) globalTest!.fail("The resolve value should be 0, but got " + res + "!") + }, (e: NullishType) : void => { + globalTest!.fail("The promise should not be rejected!") + }).catch((e: NullishType) : void => { + globalTest!.fail("The promise should not be rejected!") + }) + return globalTest + } + + public static taskpoolThrowErrorTest() : BasicTest { + let globalTest = new BasicTest(3, 'taskpoolThrowErrorTest'); + globalTest!.checkpoint(0); + let p = taskpool.execute(() : int => { + globalTest!.checkpoint(1); + throw new Error("taskpoolError") + }) + p.then((v: NullishType) : void => { + globalTest!.fail("The resolve value should not be resolved") + }).catch((e: Error) : void => { + globalTest!.checkpoint(2); + if(e.message != 'taskpoolError') globalTest!.fail("The reject reason should be \"taskpoolError\"!") + }) + return globalTest + } + + public static asyncSequenceTest() : BasicTest { + let globalTest = new BasicTest(6, 'asyncSequenceTest'); + globalTest!.checkpoint(0); + const fn = async () => { + globalTest!.checkpoint(1); + let p_async = new Promise((resolve: (v:int) => void, reject: (e:Error) => void):void => { + globalTest!.checkpoint(2); + setTimeout(():void => { + globalTest!.checkpoint(4); + resolve(0) + }, 10) + }) + await p_async; + hilog.info(0x0000, 'testTag', 'asyncseqtest after await'); + globalTest!.checkpoint(5); + } + fn() + globalTest!.checkpoint(3); + return globalTest + } + + public static runTest(testcase : Test) { + let counter = 0; + const maxCounter = 5; + const checkDelay = 1000; + let tId = 0; + let test = testcase() + let checkCallback = () => { + ++counter; + if (counter === maxCounter) { + throw new Error('Test failed: timeout.'); + } + let result = test.check(); + if (result) { + clearInterval(tId); + } + }; + tId = setInterval(checkCallback, checkDelay); + } +} + class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { hilog.info(0x0000, 'testTag', 'EntryAbility onCreate'); + + let asyncBasicTests = new Array ( + FuncTest.setTimeoutTest, + FuncTest.clearTimeoutTest, + FuncTest.promiseResolveTest, + FuncTest.promiseRejectTest, + FuncTest.taskpoolExecuteTest, + FuncTest.taskpoolThrowErrorTest, + FuncTest.asyncSequenceTest + ) + + for(let testcase of asyncBasicTests) { + // mainthread test + FuncTest.runTest(testcase) + } + + CoroutineExtras.setSchedulingPolicy(CoroutineExtras.POLICY_NON_MAIN); + for(let testcase of asyncBasicTests) { + // no mainthread test + launch FuncTest.runTest(testcase) + } + } onWindowStageCreate(windowStage: window.WindowStage): void { @@ -25,4 +197,51 @@ class EntryAbility extends UIAbility { hilog.info(0x0000, 'testTag', 'loadContent catch error:-----------' + e.message); } } +} + +class BasicTest { + constructor(numCheckpoints: int, testName: string) { + this.numCheckpoints = numCheckpoints; + this.sequence = new Array(); + this.testName = testName; + } + + check(): boolean { + if (this.result == BasicTest.RESULT_FAILED) { + return false; + } + if (this.sequence.length != this.numCheckpoints) { + hilog.info(0x0000, 'testTag', "Test " + this.testName + " failed. Expected " + this.numCheckpoints + " checkpoints, but got " + this.sequence.length); + this.result = BasicTest.RESULT_FAILED; + return false; + } + for (let i = 0; i < this.sequence.length; ++i) { + if (this.sequence[i] != i) { + hilog.info(0x0000, 'testTag',"Test " + this.testName + " failed. Expected " + i + "-th checkpoint to be " + i + ", but got " + this.sequence[i]); + this.result = BasicTest.RESULT_FAILED; + return false; + } + } + hilog.info(0x0000, 'testTag', "Test " + this.testName + " pass!") + return true; + } + + fail(message: string): void { + this.result = BasicTest.RESULT_FAILED; + hilog.info(0x0000, 'testTag', "Test "+ this.testName + " failed! "+ message); + } + + checkpoint(value: int) { + this.sequence.push(value); + } + + private static RESULT_UNSET: int = 0; + private static RESULT_PASSED: int = 1; + private static RESULT_FAILED: int = 2; + + result: int = BasicTest.RESULT_UNSET; + failMessage: string = ""; + private sequence: Array; + private numCheckpoints: int; + private testName: string = ""; } \ No newline at end of file