From a953016d4a258fe232bbf148289998f81e5673ba Mon Sep 17 00:00:00 2001 From: li_juntao Date: Wed, 13 Apr 2022 14:41:56 +0800 Subject: [PATCH] add preferences demo Signed-off-by: li_juntao --- preferences/preferenceTest/.gitignore | 16 + preferences/preferenceTest/.idea/.gitignore | 3 + preferences/preferenceTest/.idea/compiler.xml | 6 + preferences/preferenceTest/.idea/gradle.xml | 23 + .../preferenceTest/.idea/jarRepositories.xml | 25 + preferences/preferenceTest/.idea/misc.xml | 4 + preferences/preferenceTest/build.gradle | 45 ++ preferences/preferenceTest/entry/.gitignore | 2 + preferences/preferenceTest/entry/build.gradle | 32 + preferences/preferenceTest/entry/package.json | 1 + .../preferenceTest/entry/proguard-rules.pro | 1 + .../preferenceTest/entry/src/main/config.json | 63 ++ .../entry/src/main/js/MainAbility/app.js | 8 + .../src/main/js/MainAbility/i18n/en-US.json | 11 + .../src/main/js/MainAbility/i18n/zh-CN.json | 11 + .../main/js/MainAbility/pages/index/index.css | 24 + .../main/js/MainAbility/pages/index/index.hml | 7 + .../main/js/MainAbility/pages/index/index.js | 72 ++ .../js/MainAbility/pages/second/second.css | 24 + .../js/MainAbility/pages/second/second.hml | 6 + .../js/MainAbility/pages/second/second.js | 12 + .../main/resources/base/element/string.json | 12 + .../src/main/resources/base/media/icon.png | Bin 0 -> 6790 bytes preferences/preferenceTest/gradle.properties | 13 + .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 58694 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 + preferences/preferenceTest/gradlew | 183 +++++ preferences/preferenceTest/gradlew.bat | 103 +++ preferences/preferenceTest/package.json | 1 + preferences/preferenceTest/settings.gradle | 1 + preferences/systemStorageTest/.gitignore | 6 + preferences/systemStorageTest/README.en.md | 36 + preferences/systemStorageTest/README.md | 39 + preferences/systemStorageTest/README_zh.md | 5 + preferences/systemStorageTest/build.gradle | 59 ++ .../systemStorageTest/entry/build.gradle | 16 + .../entry/src/main/config.json | 62 ++ .../entry/src/main/js/default/app.js | 23 + .../entry/src/main/js/default/i18n/en-US.json | 11 + .../entry/src/main/js/default/i18n/zh-CN.json | 11 + .../src/main/js/default/pages/index/index.css | 38 + .../src/main/js/default/pages/index/index.hml | 27 + .../src/main/js/default/pages/index/index.js | 184 +++++ .../entry/src/main/js/test/List.test.js | 29 + .../main/js/test/ObjectStoreJsunit.test.js | 671 ++++++++++++++++++ .../js/test/StorageCallBackJsunit.test.js | 262 +++++++ .../main/js/test/StorageHelperJsunit.test.js | 134 ++++ .../main/js/test/StoragePromiseJsunit.test.js | 326 +++++++++ .../main/js/test/StorageSyncJsunit.test.js | 312 ++++++++ .../src/main/js/test/SystemStorage.test.js | 262 +++++++ .../main/resources/base/element/string.json | 12 + .../src/main/resources/base/media/icon.png | Bin 0 -> 6790 bytes .../screenshots/device/main.png | Bin 0 -> 29606 bytes .../screenshots/device/second.png | Bin 0 -> 30329 bytes preferences/systemStorageTest/settings.gradle | 15 + 55 files changed, 3254 insertions(+) create mode 100644 preferences/preferenceTest/.gitignore create mode 100644 preferences/preferenceTest/.idea/.gitignore create mode 100644 preferences/preferenceTest/.idea/compiler.xml create mode 100644 preferences/preferenceTest/.idea/gradle.xml create mode 100644 preferences/preferenceTest/.idea/jarRepositories.xml create mode 100644 preferences/preferenceTest/.idea/misc.xml create mode 100644 preferences/preferenceTest/build.gradle create mode 100644 preferences/preferenceTest/entry/.gitignore create mode 100644 preferences/preferenceTest/entry/build.gradle create mode 100644 preferences/preferenceTest/entry/package.json create mode 100644 preferences/preferenceTest/entry/proguard-rules.pro create mode 100644 preferences/preferenceTest/entry/src/main/config.json create mode 100644 preferences/preferenceTest/entry/src/main/js/MainAbility/app.js create mode 100644 preferences/preferenceTest/entry/src/main/js/MainAbility/i18n/en-US.json create mode 100644 preferences/preferenceTest/entry/src/main/js/MainAbility/i18n/zh-CN.json create mode 100644 preferences/preferenceTest/entry/src/main/js/MainAbility/pages/index/index.css create mode 100644 preferences/preferenceTest/entry/src/main/js/MainAbility/pages/index/index.hml create mode 100644 preferences/preferenceTest/entry/src/main/js/MainAbility/pages/index/index.js create mode 100644 preferences/preferenceTest/entry/src/main/js/MainAbility/pages/second/second.css create mode 100644 preferences/preferenceTest/entry/src/main/js/MainAbility/pages/second/second.hml create mode 100644 preferences/preferenceTest/entry/src/main/js/MainAbility/pages/second/second.js create mode 100644 preferences/preferenceTest/entry/src/main/resources/base/element/string.json create mode 100644 preferences/preferenceTest/entry/src/main/resources/base/media/icon.png create mode 100644 preferences/preferenceTest/gradle.properties create mode 100644 preferences/preferenceTest/gradle/wrapper/gradle-wrapper.jar create mode 100644 preferences/preferenceTest/gradle/wrapper/gradle-wrapper.properties create mode 100644 preferences/preferenceTest/gradlew create mode 100644 preferences/preferenceTest/gradlew.bat create mode 100644 preferences/preferenceTest/package.json create mode 100644 preferences/preferenceTest/settings.gradle create mode 100644 preferences/systemStorageTest/.gitignore create mode 100644 preferences/systemStorageTest/README.en.md create mode 100644 preferences/systemStorageTest/README.md create mode 100644 preferences/systemStorageTest/README_zh.md create mode 100644 preferences/systemStorageTest/build.gradle create mode 100644 preferences/systemStorageTest/entry/build.gradle create mode 100644 preferences/systemStorageTest/entry/src/main/config.json create mode 100644 preferences/systemStorageTest/entry/src/main/js/default/app.js create mode 100644 preferences/systemStorageTest/entry/src/main/js/default/i18n/en-US.json create mode 100644 preferences/systemStorageTest/entry/src/main/js/default/i18n/zh-CN.json create mode 100644 preferences/systemStorageTest/entry/src/main/js/default/pages/index/index.css create mode 100644 preferences/systemStorageTest/entry/src/main/js/default/pages/index/index.hml create mode 100644 preferences/systemStorageTest/entry/src/main/js/default/pages/index/index.js create mode 100644 preferences/systemStorageTest/entry/src/main/js/test/List.test.js create mode 100644 preferences/systemStorageTest/entry/src/main/js/test/ObjectStoreJsunit.test.js create mode 100644 preferences/systemStorageTest/entry/src/main/js/test/StorageCallBackJsunit.test.js create mode 100644 preferences/systemStorageTest/entry/src/main/js/test/StorageHelperJsunit.test.js create mode 100644 preferences/systemStorageTest/entry/src/main/js/test/StoragePromiseJsunit.test.js create mode 100644 preferences/systemStorageTest/entry/src/main/js/test/StorageSyncJsunit.test.js create mode 100644 preferences/systemStorageTest/entry/src/main/js/test/SystemStorage.test.js create mode 100644 preferences/systemStorageTest/entry/src/main/resources/base/element/string.json create mode 100644 preferences/systemStorageTest/entry/src/main/resources/base/media/icon.png create mode 100644 preferences/systemStorageTest/screenshots/device/main.png create mode 100644 preferences/systemStorageTest/screenshots/device/second.png create mode 100644 preferences/systemStorageTest/settings.gradle diff --git a/preferences/preferenceTest/.gitignore b/preferences/preferenceTest/.gitignore new file mode 100644 index 0000000..fdc0c4a --- /dev/null +++ b/preferences/preferenceTest/.gitignore @@ -0,0 +1,16 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +/entry/.preview +.cxx +/node_modules diff --git a/preferences/preferenceTest/.idea/.gitignore b/preferences/preferenceTest/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/preferences/preferenceTest/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/preferences/preferenceTest/.idea/compiler.xml b/preferences/preferenceTest/.idea/compiler.xml new file mode 100644 index 0000000..fb7f4a8 --- /dev/null +++ b/preferences/preferenceTest/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/preferences/preferenceTest/.idea/gradle.xml b/preferences/preferenceTest/.idea/gradle.xml new file mode 100644 index 0000000..b38a04e --- /dev/null +++ b/preferences/preferenceTest/.idea/gradle.xml @@ -0,0 +1,23 @@ + + + + + + + \ No newline at end of file diff --git a/preferences/preferenceTest/.idea/jarRepositories.xml b/preferences/preferenceTest/.idea/jarRepositories.xml new file mode 100644 index 0000000..19e238e --- /dev/null +++ b/preferences/preferenceTest/.idea/jarRepositories.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/preferences/preferenceTest/.idea/misc.xml b/preferences/preferenceTest/.idea/misc.xml new file mode 100644 index 0000000..58918f5 --- /dev/null +++ b/preferences/preferenceTest/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/preferences/preferenceTest/build.gradle b/preferences/preferenceTest/build.gradle new file mode 100644 index 0000000..66f7b5c --- /dev/null +++ b/preferences/preferenceTest/build.gradle @@ -0,0 +1,45 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'com.huawei.ohos.app' + +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + signingConfigs { + debug { + storeFile file('C:\\Users\\97216\\.ssh\\openharmony.p12') + storePassword '00000019EC436B40671A6035F5C7DB2C627FDF0CDED9BC6B2D36DC42CCAEA7A28DD992878A96FE27D6' + keyAlias = 'OpenHarmony Application CA' + keyPassword '00000019DF63265AEAE24D5690A01C18E45CC7511FB4E351EC88D504035AF3A5484671EE2D82F951E0' + signAlg = 'SHA256withECDSA' + profile file('C:\\Users\\97216\\.ssh\\SgnedReleasedProfileTemplate.p7b') + certpath file('C:\\Users\\97216\\.ssh\\IDE.cer') + } + } + compileSdkVersion 8 + supportSystem "standard" +} + +buildscript { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + } + dependencies { + classpath 'com.huawei.ohos:hap:3.0.5.2' + classpath 'com.huawei.ohos:decctest:1.2.7.2' + } +} + +allprojects { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + } +} diff --git a/preferences/preferenceTest/entry/.gitignore b/preferences/preferenceTest/entry/.gitignore new file mode 100644 index 0000000..7d5b7a9 --- /dev/null +++ b/preferences/preferenceTest/entry/.gitignore @@ -0,0 +1,2 @@ +/build +/node_modules diff --git a/preferences/preferenceTest/entry/build.gradle b/preferences/preferenceTest/entry/build.gradle new file mode 100644 index 0000000..a7868d5 --- /dev/null +++ b/preferences/preferenceTest/entry/build.gradle @@ -0,0 +1,32 @@ +apply plugin: 'com.huawei.ohos.hap' +//For instructions on signature configuration, see https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ide_debug_device-0000001053822404#section1112183053510 +ohos { + signingConfigs { + debug { + storeFile file('C:\\Users\\97216\\.ssh\\openharmony.p12') + storePassword '000000198067AF4C1B58EF8441021B634BC96F506AD34F2CC0019F5AC5384365C15C4587743AD687DD' + keyAlias = 'OpenHarmony Application CA' + keyPassword '000000192BF49F51CEBB2F656D1F492B3BEC9B8C4E5F5ED8C94FB3E7CDEB63BAFFF81E255489A24F6B' + signAlg = 'SHA256withECDSA' + profile file('C:\\Users\\97216\\.ssh\\SgnedReleasedProfileTemplate.p7b') + certpath file('C:\\Users\\97216\\.ssh\\IDE.cer') + } + } + compileSdkVersion 8 + defaultConfig { + compatibleSdkVersion 8 + } + buildTypes { + release { + proguardOpt { + proguardEnabled false + rulesFiles 'proguard-rules.pro' + } + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) + testImplementation 'junit:junit:4.13.1' +} diff --git a/preferences/preferenceTest/entry/package.json b/preferences/preferenceTest/entry/package.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/preferences/preferenceTest/entry/package.json @@ -0,0 +1 @@ +{} diff --git a/preferences/preferenceTest/entry/proguard-rules.pro b/preferences/preferenceTest/entry/proguard-rules.pro new file mode 100644 index 0000000..f7666e4 --- /dev/null +++ b/preferences/preferenceTest/entry/proguard-rules.pro @@ -0,0 +1 @@ +# config module specific ProGuard rules here. \ No newline at end of file diff --git a/preferences/preferenceTest/entry/src/main/config.json b/preferences/preferenceTest/entry/src/main/config.json new file mode 100644 index 0000000..1cd4e80 --- /dev/null +++ b/preferences/preferenceTest/entry/src/main/config.json @@ -0,0 +1,63 @@ +{ + "app": { + "bundleName": "ohos.acts.startup.js.function", + "vendor": "acts", + "version": { + "code": 1000000, + "name": "1.0.0" + } + }, + "deviceConfig": {}, + "module": { + "package": "ohos.acts.startup.js.function", + "name": ".MyApplication", + "mainAbility": ".MainAbility", + "deviceType": [ + "phone" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry", + "installationFree": false + }, + "abilities": [ + { + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "orientation": "unspecified", + "visible": true, + "srcPath": "MainAbility", + "name": ".MainAbility", + "srcLanguage": "js", + "icon": "$media:icon", + "description": "$string:mainability_description", + "formsEnabled": false, + "label": "$string:entry_MainAbility", + "type": "page", + "launchType": "standard" + } + ], + "js": [ + { + "pages": [ + "pages/index/index", + "pages/second/second" + ], + "name": ".MainAbility", + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + } + ] + } +} \ No newline at end of file diff --git a/preferences/preferenceTest/entry/src/main/js/MainAbility/app.js b/preferences/preferenceTest/entry/src/main/js/MainAbility/app.js new file mode 100644 index 0000000..6d060ff --- /dev/null +++ b/preferences/preferenceTest/entry/src/main/js/MainAbility/app.js @@ -0,0 +1,8 @@ +export default { + onCreate() { + console.info("Application onCreate"); + }, + onDestroy() { + console.info("Application onDestroy"); + } +}; diff --git a/preferences/preferenceTest/entry/src/main/js/MainAbility/i18n/en-US.json b/preferences/preferenceTest/entry/src/main/js/MainAbility/i18n/en-US.json new file mode 100644 index 0000000..08e34ea --- /dev/null +++ b/preferences/preferenceTest/entry/src/main/js/MainAbility/i18n/en-US.json @@ -0,0 +1,11 @@ +{ + "strings": { + "hello": "Hello", + "world": "World", + "page": "Second Page", + "next": "Next Page", + "back": "Back" + }, + "Files": { + } +} \ No newline at end of file diff --git a/preferences/preferenceTest/entry/src/main/js/MainAbility/i18n/zh-CN.json b/preferences/preferenceTest/entry/src/main/js/MainAbility/i18n/zh-CN.json new file mode 100644 index 0000000..3dd53b3 --- /dev/null +++ b/preferences/preferenceTest/entry/src/main/js/MainAbility/i18n/zh-CN.json @@ -0,0 +1,11 @@ +{ + "strings": { + "hello": "您好", + "world": "世界", + "page": "第二页", + "next": "下一页", + "back": "返回" + }, + "Files": { + } +} \ No newline at end of file diff --git a/preferences/preferenceTest/entry/src/main/js/MainAbility/pages/index/index.css b/preferences/preferenceTest/entry/src/main/js/MainAbility/pages/index/index.css new file mode 100644 index 0000000..31a3676 --- /dev/null +++ b/preferences/preferenceTest/entry/src/main/js/MainAbility/pages/index/index.css @@ -0,0 +1,24 @@ +.container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + left: 0px; + top: 0px; + width: 100%; + height: 100%; +} + +.title { + font-size: 60px; + text-align: center; + width: 100%; + height: 40%; + margin: 10px; +} + +.btn { + width: 50%; + height: 100px; + font-size: 40px; +} diff --git a/preferences/preferenceTest/entry/src/main/js/MainAbility/pages/index/index.hml b/preferences/preferenceTest/entry/src/main/js/MainAbility/pages/index/index.hml new file mode 100644 index 0000000..e3be462 --- /dev/null +++ b/preferences/preferenceTest/entry/src/main/js/MainAbility/pages/index/index.hml @@ -0,0 +1,7 @@ +
+ + + + + +
diff --git a/preferences/preferenceTest/entry/src/main/js/MainAbility/pages/index/index.js b/preferences/preferenceTest/entry/src/main/js/MainAbility/pages/index/index.js new file mode 100644 index 0000000..0484d2d --- /dev/null +++ b/preferences/preferenceTest/entry/src/main/js/MainAbility/pages/index/index.js @@ -0,0 +1,72 @@ +import file from '@system.file' +import featureAbility from '@ohos.ability.featureAbility'; +import data_preference from '@ohos.data.preferences'; + +export default { + data: { + title: "", + }, + onInit() { + this.title = this.$t('strings.world'); + }, + testPut: async function () { + console.info("LJT set start"); + var context = featureAbility.getContext(); + var mPref = await data_preference.getPreferences(context, 'test_preferences'); + await mPref.put('test_string', 'value'); + await mPref.put('test_boolean', true); + await mPref.put('test_num', 123.123); + }, + testGet: async function () { + console.info("LJT Get start"); + var context = featureAbility.getContext(); + var mPref = await data_preference.getPreferences(context, 'test_preferences'); + await mPref.get('test_string', 'default', function (err, data) { + console.info('LJT get string = ' + data); + }); + await mPref.get('test_boolean', false, function (err, data) { + console.info('LJT get boolean = ' + data); + }); + await mPref.get('test_num', 321, function (err, data) { + console.info('LJT get number = ' + data); + }); + + }, + testGetAllPromise: async function () { + console.info("LJT GetAll promise start"); + var context = featureAbility.getContext(); + var mPref = await data_preference.getPreferences(context, 'test_preferences'); + const promise = mPref.getAll(); + promise.then((ret) => { + console.info('LJT promise getAll test_string = ' + ret.test_string); + console.info('LJT promise getAll test_num = ' + ret.test_num); + console.info('LJT promise getAll test_boolean = ' + ret.test_boolean); + }).catch((err) => { + console.info('LJT promise getAll err = ' + err); + }); + await promise; + }, + testGetAllCallback: async function () { + console.info("LJT GetAll callback start"); + var context = featureAbility.getContext(); + var mPref = await data_preference.getPreferences(context, 'test_preferences'); + await mPref.getAll(function (err, ret) { + console.info('LJT callback getAll test_string = ' + ret.test_string); + console.info('LJT callback getAll test_num = ' + ret.test_num); + console.info('LJT callback getAll test_boolean = ' + ret.test_boolean); + }); + mPref.getAll(function(err,ret){}) + }, + testClear: async function () { + console.info("LJT Clear start"); + var context = featureAbility.getContext(); + var mPref = await data_preference.getPreferences(context, 'test_preferences'); + await mPref.clear(function (err, data) { + console.info('LJT clear success err=' + err); + console.info('LJT clear success data=' + data); + }); + } +} + + + diff --git a/preferences/preferenceTest/entry/src/main/js/MainAbility/pages/second/second.css b/preferences/preferenceTest/entry/src/main/js/MainAbility/pages/second/second.css new file mode 100644 index 0000000..31a3676 --- /dev/null +++ b/preferences/preferenceTest/entry/src/main/js/MainAbility/pages/second/second.css @@ -0,0 +1,24 @@ +.container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + left: 0px; + top: 0px; + width: 100%; + height: 100%; +} + +.title { + font-size: 60px; + text-align: center; + width: 100%; + height: 40%; + margin: 10px; +} + +.btn { + width: 50%; + height: 100px; + font-size: 40px; +} diff --git a/preferences/preferenceTest/entry/src/main/js/MainAbility/pages/second/second.hml b/preferences/preferenceTest/entry/src/main/js/MainAbility/pages/second/second.hml new file mode 100644 index 0000000..d75ce93 --- /dev/null +++ b/preferences/preferenceTest/entry/src/main/js/MainAbility/pages/second/second.hml @@ -0,0 +1,6 @@ +
+ + {{ $t('strings.page') }} + + +
diff --git a/preferences/preferenceTest/entry/src/main/js/MainAbility/pages/second/second.js b/preferences/preferenceTest/entry/src/main/js/MainAbility/pages/second/second.js new file mode 100644 index 0000000..ac4f4f8 --- /dev/null +++ b/preferences/preferenceTest/entry/src/main/js/MainAbility/pages/second/second.js @@ -0,0 +1,12 @@ +import router from '@system.router' + +export default { + data: { + title: 'World' + }, + onclick: function () { + router.replace({ + uri: "pages/index/index" + }) + } +} diff --git a/preferences/preferenceTest/entry/src/main/resources/base/element/string.json b/preferences/preferenceTest/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000..0bae6bd --- /dev/null +++ b/preferences/preferenceTest/entry/src/main/resources/base/element/string.json @@ -0,0 +1,12 @@ +{ + "string": [ + { + "name": "entry_MainAbility", + "value": "entry_MainAbility" + }, + { + "name": "mainability_description", + "value": "JS_Empty Ability" + } + ] +} \ No newline at end of file diff --git a/preferences/preferenceTest/entry/src/main/resources/base/media/icon.png b/preferences/preferenceTest/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c GIT binary patch literal 6790 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 literal 0 HcmV?d00001 diff --git a/preferences/preferenceTest/gradle/wrapper/gradle-wrapper.properties b/preferences/preferenceTest/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..f59159e --- /dev/null +++ b/preferences/preferenceTest/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://repo.huaweicloud.com/gradle/gradle-6.3-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/preferences/preferenceTest/gradlew b/preferences/preferenceTest/gradlew new file mode 100644 index 0000000..536f027 --- /dev/null +++ b/preferences/preferenceTest/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# 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 +# +# https://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. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ]; do + ls=$(ls -ld "$PRG") + link=$(expr "$ls" : '.*-> \(.*\)$') + if expr "$link" : '/.*' >/dev/null; then + PRG="$link" + else + PRG=$(dirname "$PRG")"/$link" + fi +done +SAVED="$(pwd)" +cd "$(dirname \"$PRG\")/" >/dev/null +APP_HOME="$(pwd -P)" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=$(basename "$0") + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn() { + echo "$*" +} + +die() { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$(uname)" in +CYGWIN*) + cygwin=true + ;; +Darwin*) + darwin=true + ;; +MINGW*) + msys=true + ;; +NONSTOP*) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ]; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ]; then + MAX_FD_LIMIT=$(ulimit -H -n) + if [ $? -eq 0 ]; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ]; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ]; then + APP_HOME=$(cygpath --path --mixed "$APP_HOME") + CLASSPATH=$(cygpath --path --mixed "$CLASSPATH") + JAVACMD=$(cygpath --unix "$JAVACMD") + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=$(find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null) + SEP="" + for dir in $ROOTDIRSRAW; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ]; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@"; do + CHECK=$(echo "$arg" | egrep -c "$OURCYGPATTERN" -) + CHECK2=$(echo "$arg" | egrep -c "^-") ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ]; then ### Added a condition + eval $(echo args$i)=$(cygpath --path --ignore --mixed "$arg") + else + eval $(echo args$i)="\"$arg\"" + fi + i=$(expr $i + 1) + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save() { + for i; do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/preferences/preferenceTest/gradlew.bat b/preferences/preferenceTest/gradlew.bat new file mode 100644 index 0000000..62bd9b9 --- /dev/null +++ b/preferences/preferenceTest/gradlew.bat @@ -0,0 +1,103 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle 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 + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/preferences/preferenceTest/package.json b/preferences/preferenceTest/package.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/preferences/preferenceTest/package.json @@ -0,0 +1 @@ +{} diff --git a/preferences/preferenceTest/settings.gradle b/preferences/preferenceTest/settings.gradle new file mode 100644 index 0000000..4773db7 --- /dev/null +++ b/preferences/preferenceTest/settings.gradle @@ -0,0 +1 @@ +include ':entry' diff --git a/preferences/systemStorageTest/.gitignore b/preferences/systemStorageTest/.gitignore new file mode 100644 index 0000000..32fb92c --- /dev/null +++ b/preferences/systemStorageTest/.gitignore @@ -0,0 +1,6 @@ +.idea +local.properties +build +entry/build +.gradle +.DS_Store \ No newline at end of file diff --git a/preferences/systemStorageTest/README.en.md b/preferences/systemStorageTest/README.en.md new file mode 100644 index 0000000..3ac8288 --- /dev/null +++ b/preferences/systemStorageTest/README.en.md @@ -0,0 +1,36 @@ +# JsHelloWorld + +#### Description +{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} + +#### Software Architecture +Software architecture description + +#### Installation + +1. xxxx +2. xxxx +3. xxxx + +#### Instructions + +1. xxxx +2. xxxx +3. xxxx + +#### Contribution + +1. Fork the repository +2. Create Feat_xxx branch +3. Commit your code +4. Create Pull Request + + +#### Gitee Feature + +1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md +2. Gitee blog [blog.gitee.com](https://blog.gitee.com) +3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) +4. The most valuable open source project [GVP](https://gitee.com/gvp) +5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) +6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/preferences/systemStorageTest/README.md b/preferences/systemStorageTest/README.md new file mode 100644 index 0000000..9b68cbb --- /dev/null +++ b/preferences/systemStorageTest/README.md @@ -0,0 +1,39 @@ +# JsHelloWorld + +#### 介绍 +{**以下是 Gitee 平台说明,您可以替换此简介** +Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 +无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} + +#### 软件架构 +软件架构说明 + + +#### 安装教程 + +1. xxxx +2. xxxx +3. xxxx + +#### 使用说明 + +1. xxxx +2. xxxx +3. xxxx + +#### 参与贡献 + +1. Fork 本仓库 +2. 新建 Feat_xxx 分支 +3. 提交代码 +4. 新建 Pull Request + + +#### 特技 + +1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md +2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) +3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 +4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 +5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) +6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/preferences/systemStorageTest/README_zh.md b/preferences/systemStorageTest/README_zh.md new file mode 100644 index 0000000..b947592 --- /dev/null +++ b/preferences/systemStorageTest/README_zh.md @@ -0,0 +1,5 @@ +# JsHelloWorld + +- 本示例适用于应用开发的初学者。 + + 编写两个简单的页面,实现在第一个页面点击按钮跳转到第二个页面。 diff --git a/preferences/systemStorageTest/build.gradle b/preferences/systemStorageTest/build.gradle new file mode 100644 index 0000000..e1c8320 --- /dev/null +++ b/preferences/systemStorageTest/build.gradle @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021 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. + */ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'com.huawei.ohos.app' + +ohos { + signingConfigs { + debug { + storeFile file('D:\\key\\startup.p12') + storePassword '00000019F33EAC90CD228EAD3F774CB954FBCC2D96F79F6BF5A4C865C340CF9B03EF60C4B088144EDA' + keyAlias = 'test' + keyPassword '000000194DF4F74A90DE3F81C5142D484BB8A6C679017D1014A71FC7EBE22FD8C84F5B6DE3E48FD152' + signAlg = 'SHA256withECDSA' + profile file('D:\\key\\startup.p7b') + certpath file('D:\\key\\startup.cer') + } + } + compileSdkVersion 6 + defaultConfig { + compatibleSdkVersion 6 + } +} +buildscript { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + jcenter() + } + dependencies { + classpath 'com.huawei.ohos:hap:3.0.5.2' + } +} +allprojects { + repositories { + maven { + url 'https://repo.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } + jcenter() + } +} diff --git a/preferences/systemStorageTest/entry/build.gradle b/preferences/systemStorageTest/entry/build.gradle new file mode 100644 index 0000000..921386f --- /dev/null +++ b/preferences/systemStorageTest/entry/build.gradle @@ -0,0 +1,16 @@ +apply plugin: 'com.huawei.ohos.hap' +ohos { + compileSdkVersion 6 + defaultConfig { + compatibleSdkVersion 6 + } + buildTypes { + release { + proguardOpt { + proguardEnabled false + rulesFiles 'proguard-rules.pro' + } + } + } + supportSystem "standard" +} diff --git a/preferences/systemStorageTest/entry/src/main/config.json b/preferences/systemStorageTest/entry/src/main/config.json new file mode 100644 index 0000000..3634b44 --- /dev/null +++ b/preferences/systemStorageTest/entry/src/main/config.json @@ -0,0 +1,62 @@ +{ + "app": { + "bundleName": "ohos.acts.startup.js.function", + "version": { + "code": 1000000, + "name": "1.0" + } + }, + "deviceConfig": {}, + "module": { + "package": "ohos.acts.startup.js.function", + "name": ".MyApplication", + "mainAbility": "ohos.acts.startup.js.function.MainAbility", + "reqCapabilities": [ + "video_support" + ], + "deviceType": [ + "phone" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry", + "installationFree": false + }, + "abilities": [ + { + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "orientation": "unspecified", + "visible": true, + "formsEnabled": false, + "name": ".MainAbility", + "icon": "$media:icon", + "description": "$string:mainability_description", + "label": "$string:app_name", + "type": "page", + "launchType": "standard" + } + ], + "js": [ + { + "pages": [ + "pages/index/index" + ], + "name": "default", + "window": { + "designWidth": 720, + "autoDesignWidth": false + } + } + ] + } +} \ No newline at end of file diff --git a/preferences/systemStorageTest/entry/src/main/js/default/app.js b/preferences/systemStorageTest/entry/src/main/js/default/app.js new file mode 100644 index 0000000..58d12b7 --- /dev/null +++ b/preferences/systemStorageTest/entry/src/main/js/default/app.js @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021 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 default { + onCreate() { + console.info("Application onCreate"); + }, + onDestroy() { + console.info("Application onDestroy"); + } +}; diff --git a/preferences/systemStorageTest/entry/src/main/js/default/i18n/en-US.json b/preferences/systemStorageTest/entry/src/main/js/default/i18n/en-US.json new file mode 100644 index 0000000..08e34ea --- /dev/null +++ b/preferences/systemStorageTest/entry/src/main/js/default/i18n/en-US.json @@ -0,0 +1,11 @@ +{ + "strings": { + "hello": "Hello", + "world": "World", + "page": "Second Page", + "next": "Next Page", + "back": "Back" + }, + "Files": { + } +} \ No newline at end of file diff --git a/preferences/systemStorageTest/entry/src/main/js/default/i18n/zh-CN.json b/preferences/systemStorageTest/entry/src/main/js/default/i18n/zh-CN.json new file mode 100644 index 0000000..3dd53b3 --- /dev/null +++ b/preferences/systemStorageTest/entry/src/main/js/default/i18n/zh-CN.json @@ -0,0 +1,11 @@ +{ + "strings": { + "hello": "您好", + "world": "世界", + "page": "第二页", + "next": "下一页", + "back": "返回" + }, + "Files": { + } +} \ No newline at end of file diff --git a/preferences/systemStorageTest/entry/src/main/js/default/pages/index/index.css b/preferences/systemStorageTest/entry/src/main/js/default/pages/index/index.css new file mode 100644 index 0000000..a6053c6 --- /dev/null +++ b/preferences/systemStorageTest/entry/src/main/js/default/pages/index/index.css @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 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. + */ + +.container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + left: 0px; + top: 0px; + width: 100%; + height: 100%; +} + +.title { + font-size: 60px; + text-align: center; + width: 100%; + height: 40%; + margin: 10px; +} +.btn { + width: 50%; + height: 100px; + font-size: 40px; +} diff --git a/preferences/systemStorageTest/entry/src/main/js/default/pages/index/index.hml b/preferences/systemStorageTest/entry/src/main/js/default/pages/index/index.hml new file mode 100644 index 0000000..7af5439 --- /dev/null +++ b/preferences/systemStorageTest/entry/src/main/js/default/pages/index/index.hml @@ -0,0 +1,27 @@ + + +
+ + + + + + + + + + +
diff --git a/preferences/systemStorageTest/entry/src/main/js/default/pages/index/index.js b/preferences/systemStorageTest/entry/src/main/js/default/pages/index/index.js new file mode 100644 index 0000000..dae6692 --- /dev/null +++ b/preferences/systemStorageTest/entry/src/main/js/default/pages/index/index.js @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2021 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 file from '@system.file' +import storage from '@system.storage'; +import preferences from '@ohos.data.preferences'; +import data_storage from '@ohos.data.storage'; +import featureAbility from '@ohos.ability.featureAbility'; +import {Core, ExpectExtend, ReportExtend} from 'deccjsunit/index' + +export default { + data: { + title: "", + }, + onInit() { + this.title = this.$t('strings.world'); + }, + test_storage_get: function () { + console.info('testStorageGet START'); + storage.get({ + key: "storage_key", + default: "123456", + success: function (data) { + console.info('LJT [storage.get] success: ' + data); + }, + fail: function (data, code) { + console.log('LJT [storage.get] fail, code: ' + code + ', data: ' + data); + }, + complete: function () { + console.log('LJT [storage.get] complete'); + } + }) + }, + test_storage_get2: function () { + console.info('testStorageGet START'); + storage.get({ + key: "storage_key2", + success: function (data) { + console.info('LJT [storage.get2] success: ' + data); + }, + fail: function (data, code) { + console.log('LJT [storage.get2] fail, code: ' + code + ', data: ' + data); + }, + complete: function () { + console.log('LJT [storage.get2] complete'); + } + }) + }, + test_storage_set: function () { + console.info('testStorageSet START'); + storage.set({ + key: 'storage_key', + value: 'value1', + success: function () { + console.info('LJT [storage.set] success'); + }, + fail: function (data, code) { + console.info('LJT [storage.set] fail, code: ' + code + ', data: ' + data); + }, + }); + }, + test_storage_set2: function () { + console.info('testStorageSet START'); + storage.set({ + key: 'storage_key2', + value: 'value2', + success: function () { + console.info('LJT [storage.set2] success'); + }, + fail: function (data, code) { + console.info('LJT [storage.set2] fail, code: ' + code + ', data: ' + data); + }, + }); + }, + test_storage_set3: function () { + console.info('testStorageSet START'); + storage.set({ + key: 'storage_key3', + value: 'value3', + success: function () { + console.info('LJT [storage.set3] success'); + }, + fail: function (data, code) { + console.info('LJT [storage.set3] fail, code: ' + code + ', data: ' + data); + }, + }); + }, + test_storage_set_empty: function () { + console.info('testStorageSet EMPTY START'); + storage.set({ + key: '', + value: 'value3', + success: function () { + console.info('LJT [storage.setEmpty] success'); + }, + fail: function (data, code) { + console.info('LJT [storage.setEmpty] fail, code: ' + code + ', data: ' + data); + }, + }); + }, + test_storage_set_maxKey: function () { + console.info('testStorageSet MAXKEY START'); + storage.set({ + key: 'x'.repeat(33), + value: 'max', + success: function () { + console.info('LJT [storage.setMaxKey] success'); + }, + fail: function (data, code) { + console.info('LJT [storage.setMaxKey] fail, code: ' + code + ', data: ' + data); + }, + }); + }, + test_storage_set_maxValue: function () { + console.info('testStorageSet MAXVALUE START'); + storage.set({ + key: 'max', + value: 'x'.repeat(129), + success: function () { + console.info('LJT [storage.setMaxValue] success'); + }, + fail: function (data, code) { + console.info('LJT [storage.setMaxValue] fail, code: ' + code + ', data: ' + data); + }, + }); + }, + test_storage_clear: function () { + console.info('testStorageClear START'); + storage.clear({ + success: function () { + console.info('LJT [storage.clear] success'); + }, + fail: function (data, code) { + console.info('LJT [storage.clear] fail, code: ' + code + ', data: ' + data); + }, + }) + }, + test_storage_delete: function () { + console.info('testStorageDelete START'); + storage.delete({ + key: "storage_key2", + success: function () { + console.info('LJT [storage.delete] success'); + }, + fail: function (data, code) { + console.info('LJT [storage.delete] fail, code: ' + code + ', data: ' + data); + }, + }) + }, + onclick: function () { + }, + onShow: function () { + console.info('RDB_TEST:onShow') + const core = Core.getInstance() + const expectExtend = new ExpectExtend({ + 'id': 'extend' + }) + const reportExtend = new ReportExtend(file) + core.addService('expect', expectExtend) + core.addService('report', reportExtend) + core.init() + + const configService = core.getDefaultService('config') + configService.setConfig(this) + + require('../../../test/List.test') + core.execute() + + this.title = 'RDB_TEST:onShow finished.' + console.info('RDB_TEST:onShow finished.') + } +} + diff --git a/preferences/systemStorageTest/entry/src/main/js/test/List.test.js b/preferences/systemStorageTest/entry/src/main/js/test/List.test.js new file mode 100644 index 0000000..0c2cd8a --- /dev/null +++ b/preferences/systemStorageTest/entry/src/main/js/test/List.test.js @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2021 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. +*/ +//require('./StorageHelperJsunit.test.js') +//require('./StoragePromiseJsunit.test.js') +//require('./StorageCallBackJsunit.test.js') +//require('./StorageSyncJsunit.test.js') +//require('./RdbstoreInsertJsunit.test.js') +//require('./RdbstoreDeleteJsunit.test.js') +//require('./RdbStoreResultSetJsunit.test.js') +//require('./RdbstorePredicatesJsunit.test.js') +//require('./RdbstoreRdbstoreJsunit.test.js') +//require('./RdbstoreStoreExcuteSqlJsunit.test.js') +//require('./RdbstoreUpdateJsunit.test.js') +//require('./ObjectStoreJsunit.test.js') +//require('./RdbstoreTransactionJsunit.test.js') +//require('./DataAbilityPredicatesJsunit.test1.js') +require('./SystemStorage.test.js') \ No newline at end of file diff --git a/preferences/systemStorageTest/entry/src/main/js/test/ObjectStoreJsunit.test.js b/preferences/systemStorageTest/entry/src/main/js/test/ObjectStoreJsunit.test.js new file mode 100644 index 0000000..a8d1087 --- /dev/null +++ b/preferences/systemStorageTest/entry/src/main/js/test/ObjectStoreJsunit.test.js @@ -0,0 +1,671 @@ +/* + * 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 {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from 'deccjsunit/index' +import distributedObject from '@ohos.data.distributedDataObject'; + +var baseLine = 500; //0.5 second +const TAG = "OBJECTSTORE_TEST"; + +function changeCallback(sessionId, changeData) { + console.info("get init change111" + sessionId + " " + changeData); + if (changeData != null && changeData != undefined) { + changeData.forEach(element => { + console.info(TAG + "data changed !" + element); + }); + } + console.info(TAG + "get init change111 end" + sessionId + " " + changeData); +} + +function changeCallback2(sessionId, changeData) { + console.info("get init change222" + sessionId + " " + changeData); + if (changeData != null && changeData != undefined) { + changeData.forEach(element => { + console.info(TAG + "data changed !" + element); + }); + } + console.info(TAG + "get init change222 end" + sessionId + " " + changeData); +} + +function statusCallback1(sessionId, networkId, status) { + console.info(TAG + "test init change111" + sessionId); + this.response += "\nstatus changed " + sessionId + " " + status + " " + networkId; +} + +function statusCallback2(sessionId, networkId, status) { + console.info(TAG + "test init change222" + sessionId); + this.response += "\nstatus changed " + sessionId + " " + status + " " + networkId; +} + +function statusCallback3(sessionId, networkId, status) { + console.info(TAG + "test init change333" + sessionId); + this.response += "\nstatus changed " + sessionId + " " + status + " " + networkId; +} + +describe('objectStoreTest', function () { + beforeAll(function () { + console.info(TAG + 'beforeAll') + }) + + beforeEach(function () { + console.info(TAG + 'beforeEach') + }) + + afterEach(function () { + console.info(TAG + 'afterEach') + }) + + afterAll(function () { + console.info(TAG + 'afterAll') + }) + + console.log(TAG + "*************Unit Test Begin*************"); + + + /** + * @tc.name: testOn001 + * @tc.desc: object join session and on,object can receive callback when data has been changed + * @tc.type: FUNC + * @tc.require: I4H3LS + */ + it('testOn001', 0, function (done) { + console.log(TAG + "************* testOn001 start *************"); + var g_object = distributedObject.createDistributedObject({ name: "Amy", age: 18, isVis: false }); + g_object.setSessionId("session1"); + if (g_object != undefined && g_object != null) { + expect("session1" == g_object.__sessionId); + } else { + console.log(TAG + "testOn001 joinSession failed"); + } + console.info(TAG + " start call watch change"); + g_object.on("change", changeCallback); + if (g_object != undefined && g_object != null) { + g_object.name = "jack1"; + g_object.age = 19; + g_object.isVis = true; + expect(g_object.name == "jack1"); + expect(g_object.age == 19); + console.info(TAG + " set data success!"); + } else { + console.info(TAG + " object is null,set name fail"); + } + + done() + console.log(TAG + "************* testOn001 end *************"); + }) + + /** + * @tc.name: testOn002 + * @tc.desc object join session and no on,obejct can not receive callback when data has been changed + * @tc.type: FUNC + * @tc.require: I4H3LS + */ + it('testOn002', 0, function (done) { + console.log(TAG + "************* testOn002 start *************"); + var g_object = distributedObject.createDistributedObject({ name: "Amy", age: 18, isVis: false }); + g_object.setSessionId("session2"); + if (g_object != undefined && g_object != null) { + expect("session2" == g_object.__sessionId); + } else { + console.log(TAG + "testOn002 joinSession failed"); + } + if (g_object != undefined && g_object != null) { + g_object.name = "jack1"; + g_object.age = 19; + g_object.isVis = true; + expect(g_object.name == "jack1"); + expect(g_object.age == 19); + console.info(TAG + " set data success!"); + } else { + console.info(TAG + " object is null,set name fail"); + } + + done() + console.log(TAG + "************* testOn002 end *************"); + }) + + /** + * @tc.name: testOn003 + * @tc.desc: object join session and on,then object change data twice,object can receive two callbacks when data has been changed + * @tc.type: FUNC + * @tc.require: I4H3LS + */ + it('testOn003', 0, function (done) { + console.log(TAG + "************* testOn003 start *************"); + var g_object = distributedObject.createDistributedObject({ name: "Amy", age: 18, isVis: false }); + g_object.setSessionId("session3"); + if (g_object != undefined && g_object != null) { + expect("session3" == g_object.__sessionId); + } else { + console.log(TAG + "testOn003 joinSession failed"); + } + g_object.on("change", changeCallback); + console.info(TAG + " start call watch change"); + if (g_object != undefined && g_object != null) { + g_object.name = "jack1"; + g_object.age = 19; + g_object.isVis = true; + expect(g_object.name == "jack1"); + expect(g_object.age == 19); + g_object.name = "jack2"; + g_object.age = 20; + g_object.isVis = false; + expect(g_object.name == "jack2"); + expect(g_object.age == 20); + console.info(TAG + " set data success!"); + } else { + console.info(TAG + " object is null,set name fail"); + } + + done() + console.log(TAG + "************* testOn003 end *************"); + }) + + /** + * @tc.name: testOn004 + * @tc.desc object join session and on,then object do not change data,object can not receive callbacks + * @tc.type: FUNC + * @tc.require: I4H3LS + */ + it('testOn004', 0, function (done) { + console.log(TAG + "************* testOn004 start *************"); + var g_object = distributedObject.createDistributedObject({ name: "Amy", age: 18, isVis: false }); + g_object.setSessionId("session4"); + if (g_object != undefined && g_object != null) { + expect("session4" == g_object.__sessionId); + } else { + console.log(TAG + "testOn004 joinSession failed"); + } + g_object.on("change", changeCallback); + console.info(TAG + " start call watch change"); + console.info(TAG + " end call watch change"); + + done() + console.log(TAG + "************* testOn004 end *************"); + }) + + /** + * @tc.name testOff001 + * @tc.desc object join session and on&off,object can not receive callback after off + * @tc.type: FUNC + * @tc.require: I4H3LS + */ + it('testOff001', 0, function (done) { + console.log(TAG + "************* testOff001 start *************"); + var g_object = distributedObject.createDistributedObject({ name: "Amy", age: 18, isVis: false }); + g_object.setSessionId("session5"); + if (g_object != undefined && g_object != null) { + expect("session5" == g_object.__sessionId); + } else { + console.log(TAG + "testOff001 joinSession failed"); + } + g_object.on("change", changeCallback); + console.info(TAG + " start call watch change"); + if (g_object != undefined && g_object != null) { + g_object.name = "jack1"; + g_object.age = 19; + g_object.isVis = true; + expect(g_object.name == "jack1"); + expect(g_object.age == 19); + console.info(TAG + " set data success!"); + } else { + console.info(TAG + " object is null,set name fail"); + } + g_object.off("change"); + console.info(TAG + " end call watch change"); + if (g_object != undefined && g_object != null) { + g_object.name = "jack2"; + g_object.age = 20; + g_object.isVis = false; + expect(g_object.name == "jack2"); + expect(g_object.age == 20); + console.info(TAG + " set data success!"); + } else { + console.info(TAG + " object is null,set name fail"); + } + + done() + console.log(TAG + "************* testOff001 end *************"); + }) + + /** + * @tc.name:testOff002 + * @tc.desc object join session and off,object can not receive callback + * @tc.type: FUNC + * @tc.require: I4H3LS + */ + it('testOff002', 0, function (done) { + console.log(TAG + "************* testOff002 start *************"); + var g_object = distributedObject.createDistributedObject({ name: "Amy", age: 18, isVis: false }); + g_object.setSessionId("session6"); + if (g_object != undefined && g_object != null) { + expect("session6" == g_object.__sessionId); + } else { + console.log(TAG + "testOff002 joinSession failed"); + } + g_object.off("change"); + console.info(TAG + " end call watch change"); + if (g_object != undefined && g_object != null) { + g_object.name = "jack1"; + g_object.age = 19; + g_object.isVis = true; + expect(g_object.name == "jack1"); + expect(g_object.age == 19); + console.info(TAG + " set data success!"); + } else { + console.info(TAG + " object is null,set name fail"); + } + + done() + console.log(TAG + "************* testOff002 end *************"); + }) + + /** + * @tc.name: testMultiObjectOn001 + * @tc.desc: two objects join session and on,then object change data,user can receive two callbacks from two objects + * @tc.type: FUNC + * @tc.number: SUB_DDM_DistributedD_testRdbTransactionInsert0001 + * @tc.require: I4H3LS + */ + it('testMultiObjectOn001', 0, function (done) { + console.log(TAG + "************* testMultiObjectOn001 start *************"); + var g_object = distributedObject.createDistributedObject({ name: "Amy", age: 18, isVis: false }); + g_object.setSessionId("session7"); + if (g_object != undefined && g_object != null) { + expect("session7" == g_object.__sessionId); + } else { + console.log(TAG + "testMultiObjectOn001 joinSession failed"); + } + var test_object = distributedObject.createDistributedObject({ name: "Eric", age: 81, isVis: true }); + test_object.setSessionId("testSession1"); + if (test_object != undefined && test_object != null) { + expect("testSession1").assertEqual(test_object.__sessionId); + } else { + console.log(TAG + "testMultiObjectOn001 joinSession failed"); + } + g_object.on("change", changeCallback); + test_object.on("change", changeCallback2); + console.info(TAG + " start call watch change"); + if (g_object != undefined && g_object != null) { + g_object.name = "jack1"; + g_object.age = 19; + g_object.isVis = true; + expect(g_object.name == "jack1"); + expect(g_object.age == 19); + console.info(TAG + " set data success!"); + } else { + console.info(TAG + " object is null,set name fail"); + } + if (test_object != undefined && test_object != null) { + test_object.name = "jack2"; + test_object.age = 20; + test_object.isVis = false; + expect(test_object.name == "jack2"); + expect(test_object.age == 20); + console.info(TAG + " set data success!"); + } else { + console.info(TAG + " object is null,set name fail"); + } + + done() + console.log(TAG + "************* testMultiObjectOn001 end *************"); + }) + + /** + * @tc.name: testMultiObjectOff001 + * @tc.desc: two objects join session and on&off,then two objects can not receive callbacks + * @tc.type: FUNC + * @tc.require: I4H3LS + */ + it('testMultiObjectOff001', 0, function (done) { + console.log(TAG + "************* testMultiObjectOff001 start *************"); + var g_object = distributedObject.createDistributedObject({ name: "Amy", age: 18, isVis: false }); + g_object.setSessionId("session8"); + if (g_object != undefined && g_object != null) { + expect("session8" == g_object.__sessionId); + } else { + console.log(TAG + "testMultiObjectOn002 joinSession failed"); + } + var test_object = distributedObject.createDistributedObject({ name: "Eric", age: 81, isVis: true }); + test_object.setSessionId("testSession2"); + if (test_object != undefined && test_object != null) { + expect("testSession2" == test_object.__sessionId); + } else { + console.log(TAG + "testMultiObjectOn002 joinSession failed"); + } + console.log(TAG + " start call watch change") + g_object.on("change", changeCallback); + test_object.on("change", changeCallback2); + console.info(TAG + " watch success"); + if (g_object != undefined && g_object != null) { + g_object.name = "jack1"; + g_object.age = 19; + g_object.isVis = true; + expect(g_object.name == "jack1"); + expect(g_object.age == 19); + console.info(TAG + " set data success!"); + } else { + console.info(TAG + " object is null,set name fail"); + } + if (test_object != undefined && test_object != null) { + test_object.name = "jack2"; + test_object.age = 20; + test_object.isVis = false; + expect(test_object.name == "jack2"); + expect(test_object.age == 20); + console.info(TAG + " set data success!"); + } else { + console.info(TAG + " object is null,set name fail"); + } + g_object.off("change"); + if (g_object != undefined && g_object != null) { + g_object.name = "jack3"; + g_object.age = 21; + g_object.isVis = false; + expect(g_object.name == "jack3"); + expect(g_object.age == 21); + console.info(TAG + " set data success!"); + } else { + console.info(TAG + " object is null,set name fail"); + } + test_object.off("change"); + if (test_object != undefined && test_object != null) { + test_object.name = "jack4"; + test_object.age = 22; + test_object.isVis = true; + expect(test_object.name == "jack4"); + expect(test_object.age == 22); + console.info(TAG + " set data success!"); + } else { + console.info(TAG + " object is null,set name fail"); + } + + done() + console.log(TAG + "************* testMultiObjectOff001 end *************"); + }) + + /** + * @tc.name: testChangeSession001 + * @tc.desc: objects join session,then change sessionId + * @tc.type: FUNC + * @tc.require: I4H3LS + */ + it('testChangeSession001', 0, function (done) { + console.log(TAG + "************* testChangeSession001 start *************"); + var objectTest = distributedObject.createDistributedObject({ name: "Amy", age: 18, isVis: false }); + objectTest.setSessionId("session9"); + if (objectTest != undefined && objectTest != null) { + expect("session9" == objectTest.__sessionId); + } else { + console.log(TAG + "testChangeSession001 joinSession failed"); + } + console.log(TAG+"start change sessionId"); + setTimeout(() => objectTest.setSessionId("session9"), 1000); + if (objectTest != undefined && objectTest != null) { + expect("session9" == objectTest.__sessionId); + } else { + console.log(TAG + "testChangeSession001 joinSession again failed"); + } + + done() + console.log(TAG + "************* testChangeSession001 end *************"); + }) + + /** + * @tc.name: testUndefinedType001 + * @tc.desc: object use undefined type,can not join session + * @tc.type: FUNC + * @tc.require: I4H3LS + */ + it('testUndefinedType001', 0, function (done) { + console.log(TAG + "************* testUndefinedType001 start *************"); + var undefined_object = distributedObject.createDistributedObject({ name: undefined, age: undefined, isVis: undefined }); + try { + undefined_object.setSessionId("session11"); + if (undefined_object != undefined && undefined_object != null) { + expect("session11" == undefined_object.__sessionId); + } else { + console.log(TAG + "testChangeSession001 joinSession session11 failed"); + } + } catch (error) { + console.error(TAG + error); + } + + done() + console.log(TAG + "************* testUndefinedType001 end *************"); + }) + + /** + * @tc.name: testGenSessionId001 + * @tc.desc: object generate random sessionId + * @tc.type: FUNC + * @tc.require: I4H3LS + */ + it('testGenSessionId001', 0, function (done) { + console.log(TAG + "************* testGenSessionId001 start *************"); + var sessionId = distributedObject.genSessionId(); + expect(sessionId != null && sessionId.length > 0 && typeof (sessionId) == 'string'); + + done() + console.log(TAG + "************* testGenSessionId001 end *************"); + }) + + /** + * @tc.name: testGenSessionId002 + * @tc.desc: object generate 2 random sessionId and not equal + * @tc.type: FUNC + * @tc.require: I4H3LS + */ + it('testGenSessionId002', 0, function (done) { + console.log(TAG + "************* testGenSessionId001 start *************"); + var sessionId1 = distributedObject.genSessionId(); + var sessionId2 = distributedObject.genSessionId(); + expect(sessionId1 != sessionId2); + + done() + console.log(TAG + "************* testGenSessionId002 end *************"); + }) + + /** + * @tc.name: testOnStatus001 + * @tc.desc: object set a listener to watch another object online/offline + * @tc.type: FUNC + * @tc.require: I4H3M8 + */ + it('testOnStatus001', 0, function (done) { + console.log(TAG + "************* testOnStatus001 start *************"); + console.log(TAG + "start watch status"); + var g_object = distributedObject.createDistributedObject({ name: "Amy", age: 18, isVis: false }); + g_object.on("status", statusCallback1); + console.log(TAG + "watch success"); + + done() + console.log(TAG + "************* testOnStatus001 end *************"); + }) + + /** + * @tc.name: testOnStatus002 + * @tc.desc: object set several listener and can unset specified listener + * @tc.type: FUNC + * @tc.require: I4H3M8 + */ + it('testOnStatus002', 0, function (done) { + console.log(TAG + "************* testOnStatus002 start *************"); + console.log(TAG + "start watch status"); + var g_object = distributedObject.createDistributedObject({ name: "Amy", age: 18, isVis: false }); + g_object.on("status", statusCallback1); + g_object.on("status", statusCallback2); + g_object.on("status", statusCallback3); + console.log(TAG + "watch success"); + console.log(TAG + "start call unwatch status"); + g_object.off("status", statusCallback1); + console.log(TAG + "unwatch success"); + + done() + console.log(TAG + "************* testOnStatus002 end *************"); + }) + + /** + * @tc.name: testOnStatus003 + * @tc.desc: object set several listener and can unWatch all watcher + * @tc.type: FUNC + * @tc.require: I4H3M8 + */ + it('testOnStatus003', 0, function (done) { + console.log(TAG + "************* testOnStatus003 start *************"); + console.log(TAG + "start watch status"); + var g_object = distributedObject.createDistributedObject({ name: "Amy", age: 18, isVis: false }); + g_object.on("status", statusCallback1); + g_object.on("status", statusCallback2); + g_object.on("status", statusCallback3); + console.log(TAG + "watch success"); + console.log(TAG + "start call unwatch status"); + g_object.off("status"); + console.log(TAG + "unwatch success"); + + done() + console.log(TAG + "************* testOnStatus003 end *************"); + }) + + /** + * @tc.name: testComplex001 + * @tc.desc: object can get/set complex data + * @tc.type: FUNC + * @tc.require: I4H3M8 + */ + it('testComplex001', 0, function (done) { + console.log(TAG + "************* testComplex001 start *************"); + var complex_object = distributedObject.createDistributedObject({ + name: undefined, + age: undefined, + parent: undefined, + list: undefined + }); + complex_object.setSessionId("session12"); + if (complex_object != undefined && complex_object != null) { + expect("session12" == complex_object.__sessionId); + } else { + console.log(TAG + "testOnComplex001 joinSession session12 failed"); + } + complex_object.name = "jack"; + complex_object.age = 19; + complex_object.isVis = false; + complex_object.parent = { mother: "jack mom", father: "jack Dad" }; + complex_object.list = [{ mother: "jack mom" }, { father: "jack Dad" }]; + expect(complex_object.name == "jack"); + expect(complex_object.age == 19); + expect(complex_object.parent == { mother: "jack1 mom", father: "jack1 Dad" }); + expect(complex_object.list == [{ mother: "jack1 mom", father: "jack1 Dad" }]); + + done() + console.log(TAG + "************* testComplex001 end *************"); + }) + + /** + * @tc.name: testMaxSize001 + * @tc.desc: object can get/set data under 4MB size + * @tc.type: FUNC + * @tc.require: I4H3M8 + */ + it('testMaxSize001', 0, function (done) { + console.log(TAG + "************* testMaxSize001 start *************"); + var g_object = distributedObject.createDistributedObject({ name: "Amy", age: 18, isVis: false }); + g_object.setSessionId("session13"); + if (g_object != undefined && g_object != null) { + expect("session13" == g_object.__sessionId); + } else { + console.log(TAG + "testMaxSize001 joinSession session13 failed"); + } + //maxString = 32byte + var maxString = "12345678123456781234567812345678".repeat(131072); + if (g_object != undefined && g_object != null) { + g_object.name = maxString; + g_object.age = 42; + g_object.isVis = false; + expect(g_object.name == maxString); + console.log(TAG + "get/set maxSize string success"); + } else { + console.info(TAG + " object is null,set name fail"); + } + + done() + console.log(TAG + "************* testMaxSize001 end *************"); + }) + + /** + * @tc.name: testPerformance001 + * @tc.desc: performanceTest for set/get data + * @tc.type: FUNC + * @tc.require: I4H3M8 + */ + it('testPerformance001', 0, function (done) { + console.log(TAG + "************* testPerformance001 start *************"); + var complex_object = distributedObject.createDistributedObject({ + name: undefined, + age: undefined, + parent: undefined, + list: undefined + }); + var st1; + var totalTime = 0; + var setSessionIdTime = 0; + var setTime = 0; + var onTime = 0; + var offTime = 0; + for (var i = 0;i < 100; i++) { + st1 = Date.now(); + complex_object.setSessionId("session14"); + setSessionIdTime += Date.now() - st1; + if (complex_object != undefined && complex_object != null) { + expect("session14" == complex_object.__sessionId); + } else { + console.log(TAG + "testPerformance001 joinSession session14 failed"); + } + console.info(TAG + " start call watch change"); + st1 = Date.now(); + complex_object.on("change", changeCallback); + onTime += Date.now() - st1; + console.info(TAG + "on change success"); + st1 = Date.now(); + complex_object.name = "jack2"; + complex_object.age = 20; + complex_object.isVis = false; + complex_object.parent = { mother: "jack1 mom1", father: "jack1 Dad1" }; + complex_object.list = [{ mother: "jack1 mom1" }, { father: "jack1 Dad1" }]; + setTime += Date.now() - st1; + expect(complex_object.name == "jack2"); + expect(complex_object.age == 20); + expect(complex_object.parent == { mother: "jack1 mom1", father: "jack1 Dad1" }); + expect(complex_object.list == [{ mother: "jack1 mom1", father: "jack1 Dad1" }]); + + console.log(TAG + "start unWatch change"); + st1 = Date.now(); + complex_object.off("change"); + offTime += Date.now() - st1; + totalTime += setSessionIdTime; + totalTime += setTime; + totalTime += onTime; + totalTime += offTime; + console.log(TAG + "end unWatch success"); + } + console.log(TAG + "totalTime = " + (totalTime / 100)); + expect(totalTime < baseLine); + done() + console.log(TAG + "************* testPerformance001 end *************"); + }) + + + console.log(TAG + "*************Unit Test End*************"); +}) + diff --git a/preferences/systemStorageTest/entry/src/main/js/test/StorageCallBackJsunit.test.js b/preferences/systemStorageTest/entry/src/main/js/test/StorageCallBackJsunit.test.js new file mode 100644 index 0000000..e588131 --- /dev/null +++ b/preferences/systemStorageTest/entry/src/main/js/test/StorageCallBackJsunit.test.js @@ -0,0 +1,262 @@ +/* +* Copyright (c) 2021 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 {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from 'deccjsunit/index' +import storage from '@ohos.data.storage' + +const PATH = '/data/test_storage'; +const KEY_TEST_INT_ELEMENT = 'key_test_int'; +const KEY_TEST_LONG_ELEMENT = 'key_test_long'; +const KEY_TEST_FLOAT_ELEMENT = 'key_test_float'; +const KEY_TEST_BOOLEAN_ELEMENT = 'key_test_boolean'; +const KEY_TEST_STRING_ELEMENT = 'key_test_string'; +var mPref; + +describe('storageTest', function () { + beforeAll(function () { + console.info('beforeAll') + mPref = storage.getStorageSync(PATH); + }) + + afterAll(function () { + console.info('afterAll') + storage.deleteStorageSync(PATH); + }) + + /** + * @tc.name clear callback interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0010 + * @tc.desc clear callback interface test + */ + it('testClear0012', 0, async function (done) { + mPref.putSync(KEY_TEST_STRING_ELEMENT, "test"); + mPref.flushSync(); + await mPref.clear(function (err, ret) { + expect("defaultvalue").assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue")); + done(); + }); + }) + + /** + * @tc.name has string callback interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0020 + * @tc.desc has string callback interface test + */ + it('testHasKey0032', 0, async function (done) { + mPref.putSync(KEY_TEST_STRING_ELEMENT, "test"); + await mPref.has(KEY_TEST_STRING_ELEMENT, function (err, ret) { + expect(true).assertEqual(ret); + done(); + }) + }) + + /** + * @tc.name has int callback interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0130 + * @tc.desc has int callback interface test + */ + it('testHasKey0033', 0, async function (done) { + mPref.putSync(KEY_TEST_INT_ELEMENT, 1); + await mPref.has(KEY_TEST_INT_ELEMENT, function (err, ret) { + expect(true).assertEqual(ret); + done(); + }) + }) + + /** + * @tc.name has float callback interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0140 + * @tc.desc has float callback interface test + */ + it('testHasKey0034', 0, async function (done) { + mPref.putSync(KEY_TEST_FLOAT_ELEMENT, 1.1); + await mPref.has(KEY_TEST_FLOAT_ELEMENT, function (err, ret) { + expect(true).assertEqual(ret); + done(); + }) + }) + + /** + * @tc.name has long callback interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0150 + * @tc.desc has long callback interface test + */ + it('testHasKey0035', 0, async function (done) { + mPref.putSync(KEY_TEST_LONG_ELEMENT, 0); + await mPref.has(KEY_TEST_LONG_ELEMENT, function (err, ret) { + expect(true).assertEqual(ret); + done(); + }) + }) + + /** + * @tc.name has boolean callback interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0160 + * @tc.desc has boolean callback interface test + */ + it('testHasKey0036', 0, async function (done) { + mPref.putSync(KEY_TEST_BOOLEAN_ELEMENT, false); + await mPref.has(KEY_TEST_BOOLEAN_ELEMENT, function (err, ret) { + expect(true).assertEqual(ret); + done(); + }) + }) + + /** + * @tc.name get defaultValue callback interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0030 + * @tc.desc get defaultValue callback interface test + */ + it('testGetDefValue0062', 0, async function (done) { + mPref.clearSync(); + await mPref.get(KEY_TEST_STRING_ELEMENT, "defaultValue", function (err, ret) { + expect('defaultValue').assertEqual(ret); + done(); + }) + }) + + /** + * @tc.name get float callback interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0040 + * @tc.desc get float callback interface test + */ + it('testGetFloat0072', 0, async function (done) { + mPref.clearSync(); + mPref.putSync(KEY_TEST_FLOAT_ELEMENT, 3.0); + await mPref.get(KEY_TEST_FLOAT_ELEMENT, 0.0, function (err, ret) { + expect(3.0).assertEqual(ret); + done(); + }) + }) + + /** + * @tc.name get int callback interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0050 + * @tc.desc get int callback interface test + */ + it('testGetInt0082', 0, async function (done) { + mPref.clearSync(); + mPref.putSync(KEY_TEST_INT_ELEMENT, 3); + await mPref.get(KEY_TEST_INT_ELEMENT, 0.0, function (err, ret) { + expect(3).assertEqual(ret); + done(); + }) + }) + + /** + * @tc.name get long callback interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0060 + * @tc.desc get long callback interface test + */ + it('testGetLong0092', 0, async function (done) { + mPref.clearSync(); + mPref.putSync(KEY_TEST_LONG_ELEMENT, 3); + expect(3).assertEqual(mPref.getSync(KEY_TEST_LONG_ELEMENT, 0)); + await mPref.get(KEY_TEST_LONG_ELEMENT, 0, function (err, ret) { + expect(3).assertEqual(ret); + done(); + }); + }) + + /** + * @tc.name get String callback interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0070 + * @tc.desc get String callback interface test + */ + it('testGetString102', 0, async function (done) { + mPref.clearSync(); + mPref.putSync(KEY_TEST_STRING_ELEMENT, "test"); + mPref.flushSync(); + await mPref.get(KEY_TEST_STRING_ELEMENT, "defaultvalue", function (err, ret) { + expect('test').assertEqual(ret); + done(); + }); + }) + + /** + * @tc.name put boolean callback interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0080 + * @tc.desc put boolean callback interface test + */ + it('testPutBoolean0122', 0, async function (done) { + mPref.clearSync(); + await mPref.put(KEY_TEST_BOOLEAN_ELEMENT, true, function (err, ret) { + expect(true).assertEqual(mPref.getSync(KEY_TEST_BOOLEAN_ELEMENT, false)); + mPref.flushSync(); + expect(true).assertEqual(mPref.getSync(KEY_TEST_BOOLEAN_ELEMENT, false)); + done(); + }); + }) + + /** + * @tc.name put float callback interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0090 + * @tc.desc put float callback interface test + */ + it('testPutFloat0132', 0, async function (done) { + mPref.clearSync(); + await mPref.put(KEY_TEST_FLOAT_ELEMENT, 4.0, function (err, ret) { + expect(4.0).assertEqual(mPref.getSync(KEY_TEST_FLOAT_ELEMENT, 0.0)); + mPref.flushSync(); + expect(4.0).assertEqual(mPref.getSync(KEY_TEST_FLOAT_ELEMENT, 0.0)); + done(); + }); + }) + + /** + * @tc.name put int callback interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0100 + * @tc.desc put int callback interface test + */ + it('testPutInt0142', 0, async function (done) { + mPref.clearSync(); + await mPref.put(KEY_TEST_INT_ELEMENT, 4, function (err, ret) { + expect(4).assertEqual(mPref.getSync(KEY_TEST_INT_ELEMENT, 0)); + mPref.flushSync(); + expect(4).assertEqual(mPref.getSync(KEY_TEST_INT_ELEMENT, 0)); + done(); + }); + }) + + /** + * @tc.name put long callback interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0110 + * @tc.desc put long callback interface test + */ + it('testPutLong0152', 0, async function (done) { + mPref.clearSync(); + mPref.putSync(KEY_TEST_LONG_ELEMENT, 4); + await mPref.put(KEY_TEST_LONG_ELEMENT, 4, function (err, ret) { + expect(4).assertEqual(mPref.getSync(KEY_TEST_LONG_ELEMENT, 0)); + mPref.flushSync(); + expect(4).assertEqual(mPref.getSync(KEY_TEST_LONG_ELEMENT, 0)); + done(); + }); + }) + + /** + * @tc.name put String callback interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_CallBack_0120 + * @tc.desc put String callback interface test + */ + it('testPutString0162', 0, async function (done) { + mPref.clearSync(); + await mPref.put(KEY_TEST_STRING_ELEMENT, '', function (err, ret) { + expect('').assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue")); + mPref.flushSync(); + expect('').assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue")); + done(); + }); + }) +}) \ No newline at end of file diff --git a/preferences/systemStorageTest/entry/src/main/js/test/StorageHelperJsunit.test.js b/preferences/systemStorageTest/entry/src/main/js/test/StorageHelperJsunit.test.js new file mode 100644 index 0000000..b5d89ba --- /dev/null +++ b/preferences/systemStorageTest/entry/src/main/js/test/StorageHelperJsunit.test.js @@ -0,0 +1,134 @@ +// @ts-nocheck +/* +* Copyright (c) 2021 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 {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from 'deccjsunit/index' +import storage from '@ohos.data.storage' + +const PATH = '/data/test_storage'; +var mPref; + +describe('storageTest', function () { + beforeAll(function () { + console.info('beforeAll') + mPref = storage.getStorageSync(PATH); + }) + + afterAll(function () { + console.info('afterAll') + storage.deleteStorageSync(PATH); + }) + + /** + * @tc.name getStorageSync interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0010 + * @tc.desc getStorageSync interface test + */ + it('testGetStorageHelper001', 0, function () { + mPref = storage.getStorageSync(PATH); + mPref.putSync('test', 2); + mPref.flushSync(); + var value = mPref.getSync('test', 0); + expect(value).assertEqual(2); + }) + + /** + * @tc.name getStorage interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0020 + * @tc.desc getStorage interface test + */ + it('testGetStorageHelper002', 0, async function (done) { + const promise = storage.getStorage(PATH); + promise.then((pref) => { + pref.putSync('test', 2); + pref.flushSync(); + var value = mPref.getSync('test', 0); + expect(value).assertEqual(2); + }).catch((err) => { + expect(null).assertFail(); + }); + await promise; + done(); + }) + + /** + * @tc.name removeStorageFromCacheSync interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0030 + * @tc.desc removeStorageFromCacheSync interface test + */ + it('testRemoveStorageFromCache001', 0, function () { + let perf = storage.getStorageSync('/data/test_storage1'); + perf.putSync('test', 2); + try { + storage.removeStorageFromCacheSync('/data/test_storage1'); + } catch (e) { + expect(null).assertFail(); + } + var value = mPref.getSync('test', 0); + expect(value).assertEqual(2); + }) + + /** + * @tc.name removeStorageFromCache interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0040 + * @tc.desc removeStorageFromCache interface test + */ + it('testRemoveStorageFromCache002', 0, async function (done) { + let perf = storage.getStorageSync('/data/test_storage2'); + perf = null; + const promise = storage.removeStorageFromCache('/data/test_storage2'); + promise.then((pref) => { + }).catch((err) => { + expect(null).assertFail(); + }); + await promise; + done(); + }) + + /** + * @tc.name deleteStorageSync interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0050 + * @tc.desc deleteStorageSync interface test + */ + it('testDeleteStorageHelper001', 0, function () { + let perf = storage.getStorageSync('/data/test_storage3'); + try { + storage.deleteStorageSync('/data/test_storage3'); + } catch (e) { + expect(null).assertFail(); + } + try { + perf.putSync("int", 3); + } catch (e) { + expect(null).assertFail(); + } + }) + + /** + * @tc.name deleteStorage interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0060 + * @tc.desc deleteStorage interface test + */ + it('testDeleteStorageHelper002', 0, async function (done) { + let perf = storage.getStorageSync('/data/test_storage4'); + perf = null; + const promise = storage.deleteStorage('/data/test_storage4'); + promise.then((pref) => { + }).catch((err) => { + expect(null).assertFail(); + }); + await promise; + done(); + }) +}) \ No newline at end of file diff --git a/preferences/systemStorageTest/entry/src/main/js/test/StoragePromiseJsunit.test.js b/preferences/systemStorageTest/entry/src/main/js/test/StoragePromiseJsunit.test.js new file mode 100644 index 0000000..f39ba9a --- /dev/null +++ b/preferences/systemStorageTest/entry/src/main/js/test/StoragePromiseJsunit.test.js @@ -0,0 +1,326 @@ +/* +* Copyright (c) 2021 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 {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from 'deccjsunit/index' +import storage from '@ohos.data.storage' + +const PATH = '/data/test_storage'; +const KEY_TEST_INT_ELEMENT = 'key_test_int'; +const KEY_TEST_LONG_ELEMENT = 'key_test_long'; +const KEY_TEST_FLOAT_ELEMENT = 'key_test_float'; +const KEY_TEST_BOOLEAN_ELEMENT = 'key_test_boolean'; +const KEY_TEST_STRING_ELEMENT = 'key_test_string'; +var mPref; + +describe('storageTest', function () { + beforeAll(function () { + console.info('beforeAll') + mPref = storage.getStorageSync(PATH); + }) + + afterAll(function () { + console.info('afterAll') + storage.deleteStorageSync(PATH); + }) + + /** + * @tc.name clear promise interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Promise_0010 + * @tc.desc clear promise interface test + */ + it('testClear0011', 0, async function (done) { + mPref.putSync(KEY_TEST_STRING_ELEMENT, "test"); + mPref.flushSync(); + const promise = mPref.clear(); + promise.then((ret) => { + expect("defaultvalue").assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue")); + }).catch((err) => { + expect(null).assertFail(); + }); + await promise; + done(); + }) + + /** + * @tc.name has string interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0020 + * @tc.desc has string interface test + */ + it('testHasKey0031', 0, async function (done) { + mPref.putSync(KEY_TEST_STRING_ELEMENT, "test"); + const promise = mPref.has(KEY_TEST_STRING_ELEMENT); + promise.then((ret) => { + expect(true).assertEqual(ret); + }).catch((err) => { + expect(null).assertFail(); + }); + await promise; + done(); + }) + + /** + * @tc.name has int interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0140 + * @tc.desc has int interface test + */ + it('testHasKey0032', 0, async function (done) { + mPref.putSync(KEY_TEST_INT_ELEMENT, 1); + const promise = mPref.has(KEY_TEST_INT_ELEMENT); + promise.then((ret) => { + expect(true).assertEqual(ret); + }).catch((err) => { + expect(null).assertFail(); + }); + await promise; + done(); + }) + + /** + * @tc.name has float interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0150 + * @tc.desc has float interface test + */ + it('testHasKey0033', 0, async function (done) { + mPref.putSync(KEY_TEST_FLOAT_ELEMENT, 2.0); + const promise = mPref.has(KEY_TEST_FLOAT_ELEMENT); + promise.then((ret) => { + expect(true).assertEqual(ret); + }).catch((err) => { + expect(null).assertFail(); + }); + await promise; + done(); + }) + + /** + * @tc.name has boolean interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0160 + * @tc.desc has boolean interface test + */ + it('testHasKey0034', 0, async function (done) { + mPref.putSync(KEY_TEST_BOOLEAN_ELEMENT, false); + const promise = mPref.has(KEY_TEST_BOOLEAN_ELEMENT); + promise.then((ret) => { + expect(true).assertEqual(ret); + }).catch((err) => { + expect(null).assertFail(); + }); + await promise; + done(); + }) + + /** + * @tc.name has long interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0170 + * @tc.desc has long interface test + */ + it('testHasKey0035', 0, async function (done) { + mPref.putSync(KEY_TEST_LONG_ELEMENT, 0); + const promise = mPref.has(KEY_TEST_LONG_ELEMENT); + promise.then((ret) => { + expect(true).assertEqual(ret); + }).catch((err) => { + expect(null).assertFail(); + }); + await promise; + done(); + }) + + /** + * @tc.name get string promise interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0030 + * @tc.desc get string promise interface test + */ + it('testGetDefValue0061', 0, async function (done) { + mPref.clearSync(); + const promise = mPref.get(KEY_TEST_STRING_ELEMENT, "defaultValue"); + promise.then((ret) => { + expect('defaultValue').assertEqual(ret); + }).catch((err) => { + expect(null).assertFail(); + }); + await promise; + done(); + }) + + /** + * @tc.name get float promise interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0040 + * @tc.desc get float promise interface test + */ + it('testGetFloat0071', 0, async function (done) { + mPref.clearSync(); + mPref.putSync(KEY_TEST_FLOAT_ELEMENT, 3.0); + const promise = mPref.get(KEY_TEST_FLOAT_ELEMENT, 0.0); + promise.then((ret) => { + expect(3.0).assertEqual(ret); + }).catch((err) => { + expect(null).assertFail(); + }); + await promise; + done(); + }) + + /** + * @tc.name get int promise interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0050 + * @tc.desc get int promise interface test + */ + it('testGetInt0081', 0, async function (done) { + mPref.clearSync(); + mPref.putSync(KEY_TEST_INT_ELEMENT, 3); + const promise = mPref.get(KEY_TEST_INT_ELEMENT, 0.0); + promise.then((ret) => { + expect(3).assertEqual(ret); + }).catch((err) => { + expect(null).assertFail(); + }); + await promise; + done(); + }) + + /** + * @tc.name get long promise interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0060 + * @tc.desc get long promise interface test + */ + it('testGetLong0091', 0, async function (done) { + mPref.clearSync(); + mPref.putSync(KEY_TEST_LONG_ELEMENT, 3); + const promise = mPref.get(KEY_TEST_LONG_ELEMENT, 0); + promise.then((ret) => { + expect(3).assertEqual(ret); + }).catch((err) => { + expect(null).assertFail(); + }); + await promise; + done(); + }) + + /** + * @tc.name get String promise interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0070 + * @tc.desc get String promise interface test + */ + it('testGetString101', 0, async function (done) { + mPref.clearSync(); + mPref.putSync(KEY_TEST_STRING_ELEMENT, "test"); + mPref.flushSync(); + const promise = mPref.get(KEY_TEST_STRING_ELEMENT, "defaultvalue"); + promise.then((ret) => { + expect('test').assertEqual(ret); + }).catch((err) => { + expect(null).assertFail(); + }); + await promise; + done(); + }) + + /** + * @tc.name put boolean promise interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0090 + * @tc.desc put boolean promise interface test + */ + it('testPutBoolean0121', 0, async function (done) { + mPref.clearSync(); + const promise = mPref.put(KEY_TEST_BOOLEAN_ELEMENT, true); + promise.then((ret) => { + expect(true).assertEqual(mPref.getSync(KEY_TEST_BOOLEAN_ELEMENT, false)); + mPref.flushSync(); + expect(true).assertEqual(mPref.getSync(KEY_TEST_BOOLEAN_ELEMENT, false)); + }).catch((err) => { + expect(null).assertFail(); + }); + await promise; + done(); + }) + + /** + * @tc.name put float promise interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0100 + * @tc.desc put float promise interface test + */ + it('testPutFloat0131', 0, async function (done) { + mPref.clearSync(); + const promise = mPref.put(KEY_TEST_FLOAT_ELEMENT, 4.0); + promise.then((ret) => { + expect(4.0).assertEqual(mPref.getSync(KEY_TEST_FLOAT_ELEMENT, 0.0)); + mPref.flushSync(); + expect(4.0).assertEqual(mPref.getSync(KEY_TEST_FLOAT_ELEMENT, 0.0)); + }).catch((err) => { + expect(null).assertFail(); + }); + await promise; + done(); + }) + + /** + * @tc.name put int promise interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0110 + * @tc.desc put int promise interface test + */ + it('testPutInt0141', 0, async function (done) { + mPref.clearSync(); + const promise = mPref.put(KEY_TEST_INT_ELEMENT, 4); + promise.then((ret) => { + expect(4).assertEqual(mPref.getSync(KEY_TEST_INT_ELEMENT, 0)); + mPref.flushSync(); + expect(4).assertEqual(mPref.getSync(KEY_TEST_INT_ELEMENT, 0)); + }).catch((err) => { + expect(null).assertFail(); + }); + await promise; + done(); + }) + + /** + * @tc.name put long promise interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0120 + * @tc.desc put long promise interface test + */ + it('testPutLong0151', 0, async function (done) { + mPref.clearSync(); + mPref.putSync(KEY_TEST_LONG_ELEMENT, 4); + const promise = mPref.put(KEY_TEST_LONG_ELEMENT, 4); + promise.then((ret) => { + expect(4).assertEqual(mPref.getSync(KEY_TEST_LONG_ELEMENT, 0)); + mPref.flushSync(); + expect(4).assertEqual(mPref.getSync(KEY_TEST_LONG_ELEMENT, 0)); + }).catch((err) => { + expect(null).assertFail(); + }); + await promise; + done(); + }) + + /** + * @tc.name put String promise interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Storage_0130 + * @tc.desc put String promise interface test + */ + it('testPutString0161', 0, async function (done) { + mPref.clearSync(); + mPref.putSync(KEY_TEST_STRING_ELEMENT, "abc"); + const promise = mPref.put(KEY_TEST_STRING_ELEMENT, ''); + promise.then((ret) => { + expect('').assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue")); + mPref.flushSync(); + expect('').assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue")); + }).catch((err) => { + expect(null).assertFail(); + }); + await promise; + done(); + }) +}) \ No newline at end of file diff --git a/preferences/systemStorageTest/entry/src/main/js/test/StorageSyncJsunit.test.js b/preferences/systemStorageTest/entry/src/main/js/test/StorageSyncJsunit.test.js new file mode 100644 index 0000000..fca3f28 --- /dev/null +++ b/preferences/systemStorageTest/entry/src/main/js/test/StorageSyncJsunit.test.js @@ -0,0 +1,312 @@ +/* +* Copyright (c) 2021 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 {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from 'deccjsunit/index' +import storage from '@ohos.data.storage' + +const PATH = '/data/test_storage'; +const KEY_TEST_INT_ELEMENT = 'key_test_int'; +const KEY_TEST_LONG_ELEMENT = 'key_test_long'; +const KEY_TEST_FLOAT_ELEMENT = 'key_test_float'; +const KEY_TEST_BOOLEAN_ELEMENT = 'key_test_boolean'; +const KEY_TEST_STRING_ELEMENT = 'key_test_string'; + +var mPref; +var changeResult; + +describe('storageTest', function () { + beforeAll(function() { + console.info('beforeAll') + mPref = storage.getStorageSync(PATH); + }) + + afterAll(function () { + console.info('afterAll') + storage.deleteStorageSync(PATH); + }) + +// it('testClear001', 0, function () { +// mPref.putSync(KEY_TEST_STRING_ELEMENT, "test"); +// mPref.putSync(KEY_TEST_INT_ELEMENT, 3); +// mPref.flushSync(); +// mPref.clearSync(); +// expect("defaultvalue").assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue")); +// expect(0).assertEqual(mPref.getSync(KEY_TEST_INT_ELEMENT, 0)); +// }) +// +// /** +// * @tc.name Constructor test +// * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0010 +// * @tc.desc Constructor test +// */ +// it('testConstructor002', 0, function () { +// expect(typeof mPref).assertEqual("object"); +// +// }) +// +// /** +// * @tc.name put string sync interface test +// * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0020 +// * @tc.desc put string sync interface test +// */ +// it('testHasKey003', 0, function () { +// mPref.putSync(KEY_TEST_STRING_ELEMENT, "test"); +// expect(true).assertEqual(mPref.hasSync(KEY_TEST_STRING_ELEMENT)); +// }) +// +// /** +// * @tc.name put int sync interface test +// * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0170 +// * @tc.desc put int sync interface test +// */ +// it('testHasKey004', 0, function () { +// mPref.putSync(KEY_TEST_INT_ELEMENT, 1); +// expect(true).assertEqual(mPref.hasSync(KEY_TEST_INT_ELEMENT)); +// }) +// +// /** +// * @tc.name put boolean sync interface test +// * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0180 +// * @tc.desc put boolean sync interface test +// */ +// it('testHasKey005', 0, function () { +// mPref.putSync(KEY_TEST_BOOLEAN_ELEMENT, false); +// expect(true).assertEqual(mPref.hasSync(KEY_TEST_BOOLEAN_ELEMENT)); +// }) +// +// /** +// * @tc.name put long sync interface test +// * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0190 +// * @tc.desc put long sync interface test +// */ +// it('testHasKey006', 0, function () { +// mPref.putSync(KEY_TEST_LONG_ELEMENT, 0); +// expect(true).assertEqual(mPref.hasSync(KEY_TEST_LONG_ELEMENT)); +// }) +// +// /** +// * @tc.name put float sync interface test +// * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0200 +// * @tc.desc put float sync interface test +// */ +// it('testHasKey007', 0, function () { +// mPref.putSync(KEY_TEST_FLOAT_ELEMENT, 1.1); +// expect(true).assertEqual(mPref.hasSync(KEY_TEST_FLOAT_ELEMENT)); +// }) +// +// /** +// * @tc.name put boolean sync interface test +// * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0030 +// * @tc.desc put boolean sync interface test +// */ +// it('testGetBoolean005', 0, function () { +// mPref.putSync(KEY_TEST_LONG_ELEMENT, true); +// expect(true).assertEqual(mPref.hasSync(KEY_TEST_LONG_ELEMENT)); +// }) +// +// /** +// * @tc.name get defaultValue sync interface test +// * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0040 +// * @tc.desc get defaultValue sync interface test +// */ +// it('testGetDefValue006', 0, function () { +// mPref.clearSync(); +// expect(-1).assertEqual(mPref.getSync(KEY_TEST_INT_ELEMENT, -1)); +// expect(1.0).assertEqual(mPref.getSync(KEY_TEST_FLOAT_ELEMENT, 1.0)); +// expect(10000).assertEqual(mPref.getSync(KEY_TEST_LONG_ELEMENT, 10000)); +// expect(true).assertEqual(mPref.getSync(KEY_TEST_BOOLEAN_ELEMENT, true)); +// expect('defaultValue').assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, "defaultValue")); +// }) +// +// /** +// * @tc.name put float sync interface test +// * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0050 +// * @tc.desc put float sync interface test +// */ +// it('testGetFloat007', 0, function () { +// mPref.clearSync(); +// mPref.putSync(KEY_TEST_FLOAT_ELEMENT, 3.0); +// expect(3.0).assertEqual(mPref.getSync(KEY_TEST_FLOAT_ELEMENT, 0.0)); +// expect(0.0).assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, 0.0)); +// }) +// +// /** +// * @tc.name put int sync interface test +// * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0060 +// * @tc.desc put int sync interface test +// */ +// it('testGetInt008', 0, function () { +// mPref.clearSync(); +// mPref.putSync(KEY_TEST_INT_ELEMENT, 3); +// expect(3).assertEqual(mPref.getSync(KEY_TEST_INT_ELEMENT, 0.0)); +// }) +// +// /** +// * @tc.name put long sync interface test +// * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0070 +// * @tc.desc put long sync interface test +// */ +// it('testGetLong009', 0, function () { +// mPref.clearSync(); +// mPref.putSync(KEY_TEST_LONG_ELEMENT, 3); +// expect(3).assertEqual(mPref.getSync(KEY_TEST_LONG_ELEMENT, 0)); +// expect(0).assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, 0)); +// }) +// +// /** +// * @tc.name put String & int sync interface test +// * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0080 +// * @tc.desc put String & int sync interface test +// */ +// it('testGetString10', 0, function () { +// mPref.clearSync(); +// mPref.putSync(KEY_TEST_STRING_ELEMENT, "test"); +// mPref.putSync(KEY_TEST_INT_ELEMENT, 3); +// mPref.flushSync(); +// expect('test').assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue")); +// expect('defaultvalue').assertEqual(mPref.getSync(KEY_TEST_INT_ELEMENT, "defaultvalue")); +// }) +// +// /** +// * @tc.name put boolean sync interface test +// * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0090 +// * @tc.desc put boolean sync interface test +// */ +// it('testPutBoolean012', 0, function () { +// mPref.clearSync(); +// mPref.putSync(KEY_TEST_BOOLEAN_ELEMENT, true); +// expect(true).assertEqual(mPref.getSync(KEY_TEST_BOOLEAN_ELEMENT, false)); +// mPref.flushSync(); +// expect(true).assertEqual(mPref.getSync(KEY_TEST_BOOLEAN_ELEMENT, false)); +// }) +// +// /** +// * @tc.name put float sync interface test +// * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0100 +// * @tc.desc put float sync interface test +// */ +// it('testPutFloat013', 0, function () { +// mPref.clearSync(); +// mPref.putSync(KEY_TEST_FLOAT_ELEMENT, 4.0); +// expect(4.0).assertEqual(mPref.getSync(KEY_TEST_FLOAT_ELEMENT, 0.0)); +// mPref.flushSync(); +// expect(4.0).assertEqual(mPref.getSync(KEY_TEST_FLOAT_ELEMENT, 0.0)); +// }) +// +// /** +// * @tc.name put int sync interface test +// * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0110 +// * @tc.desc put int sync interface test +// */ +// it('testPutInt014', 0, function () { +// mPref.clearSync(); +// mPref.putSync(KEY_TEST_INT_ELEMENT, 4); +// expect(4).assertEqual(mPref.getSync(KEY_TEST_INT_ELEMENT, 0)); +// mPref.flushSync(); +// expect(4).assertEqual(mPref.getSync(KEY_TEST_INT_ELEMENT, 0)); +// }) +// +// /** +// * @tc.name put long sync interface test +// * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0120 +// * @tc.desc put long sync interface test +// */ +// it('testPutLong015', 0, function () { +// mPref.clearSync(); +// mPref.putSync(KEY_TEST_LONG_ELEMENT, 4); +// expect(4).assertEqual(mPref.getSync(KEY_TEST_LONG_ELEMENT, 0)); +// mPref.flushSync(); +// expect(4).assertEqual(mPref.getSync(KEY_TEST_LONG_ELEMENT, 0)); +// }) +// +// /** +// * @tc.name put String sync interface test +// * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0130 +// * @tc.desc put String sync interface test +// */ +// it('testPutString016', 0, function () { +// mPref.clearSync(); +// mPref.putSync(KEY_TEST_STRING_ELEMENT, "abc"); +// mPref.putSync(KEY_TEST_STRING_ELEMENT, ''); +// expect('').assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue")); +// mPref.flushSync(); +// expect('').assertEqual(mPref.getSync(KEY_TEST_STRING_ELEMENT, "defaultvalue")); +// }) +// +// /** +// * @tc.name put interface test +// * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0140 +// * @tc.desc put interface test +// */ +// it('testRegisterObserver001', 0, function () { +// mPref.clearSync(); +// var observer = function (key) { +// expect('abcd').assertEqual(key); +// }; +// mPref.on('change', observer); +// mPref.putSync(KEY_TEST_STRING_ELEMENT, "abcd"); +// }) + + /** + * @tc.name repeat on interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0150 + * @tc.desc repeat on interface test + */ + it('testRegisterObserver002', 0, function () { + mPref.clearSync(); + var observer = function (key) { + console.info('testRegisterObserver001 key' + key); + expect(KEY_TEST_STRING_ELEMENT).assertEqual(key); + }; + mPref.on('change', observer); + mPref.putSync(KEY_TEST_STRING_ELEMENT, "abc"); + console.log("Observe On Test before putSync"); + mPref.flushSync(); + console.log("Observe On Test after flushSync"); + }) + + /** + * @tc.name repeat on interface test + * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0150 + * @tc.desc repeat on interface test + */ + it('testRegisterObserver004', 0, function () { + mPref.clearSync(); + var observer = function (key) { + console.info('testRegisterObserver004 key' + key); + changeResult = key; + }; + mPref.on('change', observer); + mPref.putSync(KEY_TEST_STRING_ELEMENT, "abc"); + console.log("Observe On Test before putSync"); + mPref.flushSync(); + console.log("Observe On Test after flushSync"); + expect(KEY_TEST_STRING_ELEMENT).assertEqual(changeResult); + }) + +// /** +// * @tc.name off interface test +// * @tc.number SUB_DDM_AppDataFWK_JSPreferences_Sync_0160 +// * @tc.desc off interface test +// */ +// it('testUnRegisterObserver001', 0, function () { +// var observer = function (key) { +// console.info('testUnRegisterObserver001 key' + key); +// expect('').assertEqual(key); +// }; +// mPref.on('change', observer); +// mPref.off('change', observer); +// mPref.putSync(KEY_TEST_STRING_ELEMENT, "abc"); +// }) +}) \ No newline at end of file diff --git a/preferences/systemStorageTest/entry/src/main/js/test/SystemStorage.test.js b/preferences/systemStorageTest/entry/src/main/js/test/SystemStorage.test.js new file mode 100644 index 0000000..f3e5b5d --- /dev/null +++ b/preferences/systemStorageTest/entry/src/main/js/test/SystemStorage.test.js @@ -0,0 +1,262 @@ +/* +* 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 {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from 'deccjsunit/index' +import storage from '@system.storage'; + +const TAG = '[SYSTEM_STORAGE_JSKITS_TEST]' +describe('systemStorageTest', function () { + beforeAll(function () { + console.info(TAG + 'beforeAll') + }) + + afterAll(function () { + console.info(TAG + 'afterAll') + storage.clear({ + success: function () { + console.info(TAG + 'afterAll clear success') + }, + fail: function (data, errCode) { + console.info(TAG + 'afterAll clear fail, data = ' + data + ', errCode = ' + errCode) + } + }) + }) + + /** + * @tc.name testSet001 + * @tc.number SUB_DDM_AppDataFWK_SystemStorage_Set_0001 + * @tc.desc set and can get correct value in success callback, finally get complete callback + */ + it('testSet001', 0, async function (done) { + console.log(TAG + '************* testSet001 start *************'); + var completeRet = false; + storage.set({ + key: 'storageKey', + value: 'testValue', + success: function () { + var getValue; + storage.get({ + key: 'storageKey', + success: function (data) { + getValue = data; + } + }) + expect(getValue).assertEquals('testValue'); + }, + complete: function () { + completeRet = true; + } + }) + setTimeout(() => expect(completeRet), 500); + + done(); + + console.log(TAG + '************* testSet001 end *************'); + }) + + /** + * @tc.name testSet002 + * @tc.number SUB_DDM_AppDataFWK_SystemStorage_Set_0002 + * @tc.desc set null key can receive fail callback + */ + it('testSet002', 0, async function (done) { + console.log(TAG + '************* testSet002 start *************'); + var testData = undefined; + var testErrCode = undefined; + storage.set({ + key: '', + value: 'testValue', + success: function () { + }, + fail: function (data, errCode) { + testData = data; + testErrCode = errCode; + } + }) + + expect(testData != undefined); + expect(testErrCode != undefined); + + done(); + + console.log(TAG + '************* testSet002 end *************'); + }) + + /** + * @tc.name testSet003 + * @tc.number SUB_DDM_AppDataFWK_SystemStorage_Set_0003 + * @tc.desc set key which size over 32 bytes and can receive fail callback + */ + /* + it('testSet003', 0, async function (done) { + console.log(TAG + '************* testSet003 start *************'); + var testData = undefined; + var testErrCode = undefined; + storage.set({ + key: 'x'.repeat(33), + value: 'testValue', + success: function () { + }, + fail: function (data, errCode) { + testData = data; + testErrCode = errCode; + } + }) + + setTimeout(function () { + expect(testData != undefined); + expect(testErrCode != undefined); + }, 500); + + done(); + + console.log(TAG + '************* testSet003 end *************'); + }) + + */ + /** + * @tc.name testSet003 + * @tc.number SUB_DDM_AppDataFWK_SystemStorage_Set_0004 + * @tc.desc set value which size over 128 bytes and can receive fail callback + */ + /* + it('testSet004', 0, async function (done) { + console.log(TAG + '************* testSet004 start *************'); + var testData = undefined; + var testErrCode = undefined; + storage.set({ + key: 'testKey', + value: 'x'.repeat(129), + success: function () { + }, + fail: function (data, errCode) { + testData = data; + testErrCode = errCode; + } + }) + + setTimeout(function () { + expect(testData != undefined); + expect(testErrCode != undefined); + }, 500); + + done(); + + console.log(TAG + '************* testSet004 end *************'); + }) + + */ + /** + * @tc.name testGet001 + * @tc.number SUB_DDM_AppDataFWK_SystemStorage_Get_0001 + * @tc.desc set and can get correct value in success callback, finally receive a get complete callback + */ + /* + it('testGet001', 0, async function (done) { + console.log(TAG + '************* testGet001 start *************'); + var completeRet = false; + storage.set({ + key: 'storageKey', + value: 'testValue', + success: function () { + var getValue; + storage.get({ + key: 'storageKey', + success: function (data) { + getValue = data; + }, + complete: function () { + completeRet = true; + } + }) + expect(getValue).assertEquals('testValue'); + } + }) + setTimeout(() => expect(true).assertEquals(completeRet), 500); + + done(); + + console.log(TAG + '************* testGet001 end *************'); + }) + + */ + /** + * @tc.name testGet002 + * @tc.number SUB_DDM_AppDataFWK_SystemStorage_Get_0002 + * @tc.desc get value without set any value and can get default in success callback + */ + /* + it('testGet002', 0, async function (done) { + console.log(TAG + '************* testGet002 start *************'); + var testVal = undefined; + var completeRet = false; + storage.get({ + key: 'storageKey', + default: '123', + success: function (data) { + testVal = data; + }, + complete: function () { + completeRet = true; + } + }) + + setTimeout(function () { + expect(true).assertEquals(completeRet); + expect('123').assertEquals(testVal); + }, 500); + + done(); + + console.log(TAG + '************* testGet002 end *************'); + }) + + */ + /** + * @tc.name testGet003 + * @tc.number SUB_DDM_AppDataFWK_SystemStorage_Get_0003 + * @tc.desc set default size over 128 and can receive fail callback + */ + /* + it('testGet003', 0, async function (done) { + console.log(TAG + '************* testGet003 start *************'); + var testVal = undefined; + var completeRet = false; + var failRet = false; + storage.get({ + key: 'storageKey', + default: 'x'.repeat(129), + success: function (data) { + testVal = data; + }, + fail: function(){ + failRet = true; + }, + complete: function () { + completeRet = true; + } + }) + + setTimeout(function () { + expect(true).assertEquals(failRet); + expect(true).assertEquals(completeRet); + }, 500); + + done(); + + console.log(TAG + '************* testGet003 end *************'); + })*/ + + +}) \ No newline at end of file diff --git a/preferences/systemStorageTest/entry/src/main/resources/base/element/string.json b/preferences/systemStorageTest/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000..76e501f --- /dev/null +++ b/preferences/systemStorageTest/entry/src/main/resources/base/element/string.json @@ -0,0 +1,12 @@ +{ + "string": [ + { + "name": "app_name", + "value": "JsHelloWorld" + }, + { + "name": "mainability_description", + "value": "hap sample empty page" + } + ] +} \ No newline at end of file diff --git a/preferences/systemStorageTest/entry/src/main/resources/base/media/icon.png b/preferences/systemStorageTest/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c GIT binary patch literal 6790 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 Lsb1;Do4@}*#^$;e literal 0 HcmV?d00001 diff --git a/preferences/systemStorageTest/screenshots/device/second.png b/preferences/systemStorageTest/screenshots/device/second.png new file mode 100644 index 0000000000000000000000000000000000000000..ab6bbc1b9c7e065ac0bbd3dbd6468ae345c3767a GIT binary patch literal 30329 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ਜ਼qZi5z|1t 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