• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifdef TEST_DEFINE_CLASS_WITH_OPTIONS
16 #include "jsvmtest.h"
17 
18 #define JSVM_PARENT_CLASS_DES_COUNT 2
19 #define JSVM_OBJECT_INTERFAIELD_COUNT 3
20 #define JSVM_DEFINE_CLASS_OPTIONS_COUNT 2
21 
22 static JSVM_PropertyHandlerConfigurationStruct propertyCfg{
23     nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr
24 };
25 
26 static bool g_callAsFunctionFlag = false;
27 static bool g_setNamedPropertyFlag = false;
28 static bool g_callAsConstructorFlag = false;
29 static bool g_propertiesFlag = false;
30 
SetNamedPropertyCbInfo2(JSVM_Env env,JSVM_Value name,JSVM_Value property,JSVM_Value thisArg,JSVM_Value data)31 static JSVM_Value SetNamedPropertyCbInfo2(JSVM_Env env, JSVM_Value name, JSVM_Value property,
32     JSVM_Value thisArg, JSVM_Value data)
33 {
34     g_setNamedPropertyFlag = true;
35     return property;
36 }
37 
Add(JSVM_Env env,JSVM_CallbackInfo info)38 static JSVM_Value Add(JSVM_Env env, JSVM_CallbackInfo info)
39 {
40     g_propertiesFlag = true;
41     size_t argc = 2;
42     JSVM_Value args[2];
43     OH_JSVM_GetCbInfo(env, info, &argc, args, NULL, NULL);
44     double num1, num2;
45     OH_JSVM_GetValueDouble(env, args[0], &num1);
46     OH_JSVM_GetValueDouble(env, args[1], &num2);
47     JSVM_Value sum = nullptr;
48     OH_JSVM_CreateDouble(env, num1 + num2, &sum);
49     return sum;
50 }
51 
GenerateParentClass(JSVM_Env env)52 JSVM_Value GenerateParentClass(JSVM_Env env)
53 {
54     JSVM_Value parentClass = nullptr;
55     JSVM_CallbackStruct *parentClassConstructor = new JSVM_CallbackStruct;
56     parentClassConstructor->data = nullptr;
57     parentClassConstructor->callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
58         JSVM_Value thisVar = nullptr;
59         OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr);
60         return thisVar;
61     };
62     JSVM_Value fooVal = jsvm::Str("bar");
63     JSVM_PropertyDescriptor des[2];
64     des[0] = {
65         .utf8name = "foo",
66         .value = fooVal,
67     };
68     JSVM_CallbackStruct *addMethod = new JSVM_CallbackStruct;
69     addMethod->data = nullptr;
70     addMethod->callback = Add;
71     des[1] = {
72         .utf8name = "add",
73         .method = addMethod,
74     };
75     JSVM_DefineClassOptions options[1];
76     options[0].id = JSVM_DEFINE_CLASS_WITH_COUNT;
77     options[0].content.num = JSVM_OBJECT_INTERFAIELD_COUNT;
78     JSVMTEST_CALL(OH_JSVM_DefineClassWithOptions(env, "parentClass", JSVM_AUTO_LENGTH,
79         parentClassConstructor, JSVM_PARENT_CLASS_DES_COUNT, des,
80         nullptr, 1, options, &parentClass));
81     return parentClass;
82 }
83 
GenerateSubClass(JSVM_Env env,JSVM_Value parentClass)84 JSVM_Value GenerateSubClass(JSVM_Env env, JSVM_Value parentClass)
85 {
86     JSVM_Value subClass = nullptr;
87     JSVM_CallbackStruct *subClassConstructor = new JSVM_CallbackStruct;
88     subClassConstructor->data = nullptr;
89     subClassConstructor->callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
90         JSVM_Value thisVar = nullptr;
91         g_callAsConstructorFlag = true;
92         OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr);
93         return thisVar;
94     };
95     JSVM_DefineClassOptions subOptions[2];
96     JSVM_CallbackStruct *callAsFuncParam = new JSVM_CallbackStruct;
97     callAsFuncParam->data = nullptr;
98     callAsFuncParam->callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
99         JSVM_Value thisVar = nullptr;
100         g_callAsFunctionFlag = true;
101         OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr);
102         return thisVar;
103     };
104     propertyCfg.genericNamedPropertySetterCallback = SetNamedPropertyCbInfo2;
105     JSVM_PropertyHandler propertyHandler = {
106         .propertyHandlerCfg = &propertyCfg,
107         .callAsFunctionCallback = callAsFuncParam,
108     };
109     subOptions[0].id = JSVM_DEFINE_CLASS_WITH_COUNT;
110     subOptions[0].content.num = JSVM_OBJECT_INTERFAIELD_COUNT;
111     subOptions[1].id = JSVM_DEFINE_CLASS_WITH_PROPERTY_HANDLER;
112     subOptions[1].content.ptr = &propertyHandler;
113     JSVMTEST_CALL(OH_JSVM_DefineClassWithOptions(env, "subClass", JSVM_AUTO_LENGTH, subClassConstructor, 0, nullptr,
114         parentClass, JSVM_DEFINE_CLASS_OPTIONS_COUNT, subOptions, &subClass));
115     return subClass;
116 }
117 
118 /**
119  * @brief Verify the validity of the following parameters in the OH_JSVM_DefineClassWithOptions interface:
120  * 'consturctor' | 'properties' | 'parentClass' | 'options'
121  */
TEST(TestParentClassWithCount)122 TEST(TestParentClassWithCount)
123 {
124     g_callAsFunctionFlag = false;
125     g_setNamedPropertyFlag = false;
126     g_callAsConstructorFlag = false;
127     g_propertiesFlag = false;
128     // 1. Define parent-class.
129     JSVM_Value parentClass = GenerateParentClass(env);
130     // 2. Define sub-class.
131     JSVM_Value subClass = GenerateSubClass(env, parentClass);
132     // 3. Verify the validity of 'constructor'.
133     JSVM_Value subInstance;
134     CHECK(g_callAsConstructorFlag == false);
135     JSVM_CALL(OH_JSVM_NewInstance(env, subClass, 0, nullptr, &subInstance));
136     CHECK(g_callAsConstructorFlag == true);
137 
138     JSVM_Value globalVal;
139     OH_JSVM_GetGlobal(env, &globalVal);
140     OH_JSVM_SetNamedProperty(env, globalVal, "obj", subInstance);
141 
142     // 4. Verify the validity of 'parentClass'.
143     JSVM_Value subRes = nullptr;
144     JSVM_CALL(OH_JSVM_GetNamedProperty(env, subInstance, "foo", &subRes));
145     CHECK(jsvm::ToString(subRes).compare("bar") == 0);
146     // 5. Verify the validity of 'properties'.
147     CHECK(g_propertiesFlag == false);
148     jsvm::Run("obj.add(3, 4);");
149     CHECK(g_propertiesFlag == true);
150     // 6. Verify the validity of 'options'.
151     CHECK(g_callAsFunctionFlag == false);
152     jsvm::Run("obj()");
153     CHECK(g_callAsFunctionFlag == true);
154     CHECK(g_setNamedPropertyFlag == false);
155     jsvm::Run("obj.x = 123;");
156     CHECK(g_setNamedPropertyFlag == true);
157 }
158 
159 /**
160  * @brief If parentClass is not an APIFunction, the status code is JSVM_INVALID_ARG.
161  */
TEST(NonAPIFunction)162 TEST(NonAPIFunction) {
163     JSVM_Value script  = jsvm::Str("return 2 + 3;");
164     JSVM_Value nonAPIFunction = nullptr;
165     JSVMTEST_CALL(OH_JSVM_CreateFunctionWithScript(env, nullptr, 0, 0,
166 	    nullptr, script, &nonAPIFunction));
167 
168     JSVM_Value subClass = nullptr;
169     JSVM_CallbackStruct constructor;
170     constructor.data = nullptr;
171     constructor.callback = [](JSVM_Env env, JSVM_CallbackInfo info) -> JSVM_Value {
172         JSVM_Value thisVar = nullptr;
173         OH_JSVM_GetCbInfo(env, info, nullptr, nullptr, &thisVar, nullptr);
174         return thisVar;
175     };
176     JSVM_Status status = OH_JSVM_DefineClassWithOptions(env, "subClass", JSVM_AUTO_LENGTH,
177         &constructor, 0, nullptr, nonAPIFunction, 0, nullptr, &subClass);
178     CHECK(status == JSVM_INVALID_ARG);
179 }
180 
181 #endif // TEST_DEFINE_CLASS_WITH_OPTIONS