1 /*
2 * Copyright (c) 2021 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
16 #include "ecmascript/ic/proto_change_details.h"
17 #include "ecmascript/global_env.h"
18 #include "ecmascript/tagged_array.h"
19 #include "ecmascript/tests/test_helper.h"
20 #include "ecmascript/weak_vector.h"
21
22 using namespace panda::ecmascript;
23
24 namespace panda::test {
25 class ProtoChangeDetailsTest : public testing::Test {
26 public:
SetUpTestCase()27 static void SetUpTestCase()
28 {
29 GTEST_LOG_(INFO) << "SetUpTestCase";
30 }
31
TearDownTestCase()32 static void TearDownTestCase()
33 {
34 GTEST_LOG_(INFO) << "TearDownCase";
35 }
36
SetUp()37 void SetUp() override
38 {
39 TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
40 }
41
TearDown()42 void TearDown() override
43 {
44 TestHelper::DestroyEcmaVMWithScope(instance, scope);
45 }
46
47 EcmaVM *instance {nullptr};
48 EcmaHandleScope *scope {nullptr};
49 JSThread *thread {nullptr};
50 };
51
52 /**
53 * @tc.name: SetBitField
54 * @tc.desc: Check whether the result returned through "GetBitField" function is within expectations.
55 * @tc.type: FUNC
56 * @tc.require:
57 */
HWTEST_F_L0(ProtoChangeDetailsTest,SetBitField)58 HWTEST_F_L0(ProtoChangeDetailsTest, SetBitField)
59 {
60 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
61 JSHandle<ProtoChangeMarker> handleProtoChangeMarker = factory->NewProtoChangeMarker();
62
63 handleProtoChangeMarker->SetBitField(true);
64 EXPECT_TRUE(handleProtoChangeMarker->GetBitField());
65
66 handleProtoChangeMarker->SetBitField(false);
67 EXPECT_FALSE(handleProtoChangeMarker->GetBitField());
68 }
69
70 /**
71 * @tc.name: SetHasChanged
72 * @tc.desc: Check whether the result returned through "GetHasChanged" function is within expectations.
73 * @tc.type: FUNC
74 * @tc.require:
75 */
HWTEST_F_L0(ProtoChangeDetailsTest,SetHasChanged)76 HWTEST_F_L0(ProtoChangeDetailsTest, SetHasChanged)
77 {
78 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
79 JSHandle<ProtoChangeMarker> handleProtoChangeMarker = factory->NewProtoChangeMarker();
80
81 handleProtoChangeMarker->SetHasChanged(true);
82 EXPECT_TRUE(handleProtoChangeMarker->GetHasChanged());
83
84 handleProtoChangeMarker->SetHasChanged(false);
85 EXPECT_FALSE(handleProtoChangeMarker->GetHasChanged());
86 }
87
88 /**
89 * @tc.name: SetChangeListener
90 * @tc.desc: Check whether the result returned through "GetChangeListener" function is within expectations.
91 * @tc.type: FUNC
92 * @tc.require:
93 */
HWTEST_F_L0(ProtoChangeDetailsTest,SetChangeListener)94 HWTEST_F_L0(ProtoChangeDetailsTest, SetChangeListener)
95 {
96 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
97 JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(1));
98
99 uint32_t weakVectorCapacity = 100;
100 JSHandle<WeakVector> weakVector = WeakVector::Create(thread, weakVectorCapacity);
101 JSHandle<ChangeListener> handleChangeListener = JSHandle<ChangeListener>::Cast(weakVector);
102 JSHandle<ProtoChangeDetails> handleChangeDetails = factory->NewProtoChangeDetails();
103
104 handleChangeDetails->SetChangeListener(thread, handleValue.GetTaggedValue());
105 EXPECT_EQ(handleChangeDetails->GetChangeListener().GetInt(), 1);
106 handleChangeDetails->SetChangeListener(thread, handleChangeListener.GetTaggedValue());
107 EXPECT_EQ(handleChangeDetails->GetChangeListener(), handleChangeListener.GetTaggedValue());
108 }
109
110 /**
111 * @tc.name: SetRegisterIndex
112 * @tc.desc: Check whether the result returned through "GetRegisterIndex" function is within expectations.
113 * @tc.type: FUNC
114 * @tc.require:
115 */
HWTEST_F_L0(ProtoChangeDetailsTest,SetRegisterIndex)116 HWTEST_F_L0(ProtoChangeDetailsTest, SetRegisterIndex)
117 {
118 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
119 JSHandle<ProtoChangeDetails> handleChangeDetails = factory->NewProtoChangeDetails();
120
121 handleChangeDetails->SetRegisterIndex(static_cast<uint32_t>(1));
122 EXPECT_EQ(handleChangeDetails->GetRegisterIndex(), 1U);
123 }
124
125 /**
126 * @tc.name: Add_001
127 * @tc.desc: Create a weakvector object with a length of ten,Call the "pushback" function to set the value of the
128 * vector.the vector is not fully set,convert the weakvector object into a ChangeListener object.In this case,
129 * call the "add" function to add a jshclass object. The added jshclass object will create and get weakref and
130 * return the location of the added object.
131 * @tc.type: FUNC
132 * @tc.require:
133 */
HWTEST_F_L0(ProtoChangeDetailsTest,Add_001)134 HWTEST_F_L0(ProtoChangeDetailsTest, Add_001)
135 {
136 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
137 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
138 JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
139 JSHandle<JSObject> handleObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
140 JSHandle<JSTaggedValue> objClassVal(thread, handleObj->GetJSHClass());
141 uint32_t weakVectorCapacity = 10;
142 uint32_t index = 2;
143 JSHandle<WeakVector> weakVector = WeakVector::Create(thread, weakVectorCapacity);
144 for (int i = 0; i < 9; i++) {
145 weakVector->PushBack(thread, JSTaggedValue(i));
146 } // weakVector is not full
147 JSHandle<ChangeListener> handleChangeListenerArr = JSHandle<ChangeListener>::Cast(weakVector);
148 JSHandle<ChangeListener> resultListenerArray =
149 ChangeListener::Add(thread, handleChangeListenerArr, JSHandle<JSHClass>(objClassVal), &index);
150 EXPECT_EQ(index, 9U);
151 JSTaggedValue weakRefValue(objClassVal.GetTaggedValue());
152 weakRefValue.CreateWeakRef();
153 EXPECT_EQ(resultListenerArray->Get(index).GetTaggedObject(), weakRefValue.GetTaggedWeakRef());
154 }
155
156 /**
157 * @tc.name: Add_002
158 * @tc.desc: Create a weakvector object with a length of ten,Call the "pushback" function to set the value of the
159 * vector the vector is fully set but exist hole,convert the weakvector object into a ChangeListener object
160 * in this case call the "add" function to add a jshclass object. The added jshclass object will create and
161 * get weakref and return the location of the added object.
162 * @tc.type: FUNC
163 * @tc.require:
164 */
HWTEST_F_L0(ProtoChangeDetailsTest,Add_002)165 HWTEST_F_L0(ProtoChangeDetailsTest, Add_002)
166 {
167 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
168 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
169 JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
170 JSHandle<JSObject> handleObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
171 JSHandle<JSTaggedValue> objClassVal(thread, handleObj->GetJSHClass());
172 uint32_t weakVectorCapacity = 10;
173 uint32_t index = 2;
174 JSHandle<WeakVector> weakVector = WeakVector::Create(thread, weakVectorCapacity);
175 for (int i = 0; i < 10; i++) {
176 weakVector->PushBack(thread, JSTaggedValue(i));
177 }
178 JSHandle<ChangeListener> handleChangeListenerArr = JSHandle<ChangeListener>::Cast(weakVector);
179 // weakVector exist hole
180 weakVector->Delete(thread, 1); // delete in one
181 JSHandle<ChangeListener> resultListenerArray =
182 ChangeListener::Add(thread, handleChangeListenerArr, JSHandle<JSHClass>(objClassVal), &index);
183 EXPECT_EQ(index, 1U);
184 JSTaggedValue weakRefValue(objClassVal.GetTaggedValue());
185 weakRefValue.CreateWeakRef();
186 EXPECT_EQ(resultListenerArray->Get(index).GetTaggedObject(), weakRefValue.GetTaggedWeakRef());
187 }
188
189 /**
190 * @tc.name: Add_003
191 * @tc.desc: Create a weakvector object with a length of ten,Call the "pushback" function to set the value of the
192 * vector the vector is fully set and not exist hole,convert the weakvector object into a ChangeListener
193 * object.in this case call the "add" function increase the length to add the jshclass object. The added
194 * jshclass object will create and get weakref and return the location of the added object.
195 * @tc.type: FUNC
196 * @tc.require:
197 */
HWTEST_F_L0(ProtoChangeDetailsTest,Add_003)198 HWTEST_F_L0(ProtoChangeDetailsTest, Add_003)
199 {
200 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
201 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
202 JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
203 JSHandle<JSObject> handleObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
204 JSHandle<JSTaggedValue> objClassVal(thread, handleObj->GetJSHClass());
205 uint32_t weakVectorCapacity = 10;
206 uint32_t index = 2;
207 JSHandle<WeakVector> weakVector = WeakVector::Create(thread, weakVectorCapacity);
208 for (int i = 0; i < 10; i++) {
209 weakVector->PushBack(thread, JSTaggedValue(i));
210 }
211 JSHandle<ChangeListener> handleChangeListenerArr = JSHandle<ChangeListener>::Cast(weakVector);
212 // weakVector is full and no hole exists.
213 JSHandle<ChangeListener> resultListenerArray =
214 ChangeListener::Add(thread, handleChangeListenerArr, JSHandle<JSHClass>(objClassVal), &index);
215 EXPECT_EQ(index, 10U);
216 JSTaggedValue weakRefValue(objClassVal.GetTaggedValue());
217 weakRefValue.CreateWeakRef();
218 EXPECT_EQ(resultListenerArray->Get(index).GetTaggedObject(), weakRefValue.GetTaggedWeakRef());
219 }
220
221 /**
222 * @tc.name: CheckHole
223 * @tc.desc: Create a weakvector object with a length of ten,Call the "pushback" function to set the value of the
224 * vector the vector is fully set,convert the weakvector object into a ChangeListener object.ChangeListener
225 * object call the "CheckHole" function to check whether there is a hole. If there is, return the location
226 * of the hole If not, return the maximum value.
227 * @tc.type: FUNC
228 * @tc.require:
229 */
HWTEST_F_L0(ProtoChangeDetailsTest,CheckHole)230 HWTEST_F_L0(ProtoChangeDetailsTest, CheckHole)
231 {
232 uint32_t weakVectorCapacity = 10;
233 JSHandle<WeakVector> weakVector = WeakVector::Create(thread, weakVectorCapacity);
234 for (int i = 0; i < 10; i++) {
235 weakVector->PushBack(thread, JSTaggedValue(i)); // Set Value and End
236 }
237 JSHandle<ChangeListener> handleChangeListenerArr = JSHandle<ChangeListener>::Cast(weakVector);
238 EXPECT_EQ(ChangeListener::CheckHole(handleChangeListenerArr), TaggedArray::MAX_ARRAY_INDEX);
239 weakVector->Delete(thread, 1);
240 EXPECT_EQ(ChangeListener::CheckHole(handleChangeListenerArr), 1U);
241 }
242
243 /**
244 * @tc.name: Get
245 * @tc.desc: Create a weakvector object with a length of three,Call the "pushback" function to set the value of the
246 * vector the vector is fully set,convert the weakvector object into a ChangeListener object.check whether
247 * the return value of calling "Get" function is the same as the value set by calling the "Set" function.
248 * @tc.type: FUNC
249 * @tc.require:
250 */
HWTEST_F_L0(ProtoChangeDetailsTest,Get)251 HWTEST_F_L0(ProtoChangeDetailsTest, Get)
252 {
253 uint32_t weakVectorCapacity = 3;
254 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
255 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
256 JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
257 JSHandle<JSTaggedValue> handleObj(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun));
258 JSHandle<WeakVector> weakVector = WeakVector::Create(thread, weakVectorCapacity);
259 // create weakref
260 JSTaggedValue objValue(handleObj.GetTaggedValue());
261 objValue.CreateWeakRef();
262 // set value for vector
263 weakVector->Set(thread, 0, JSTaggedValue(0));
264 weakVector->Set(thread, 1, objValue);
265 weakVector->Set(thread, 2, JSTaggedValue::Undefined());
266 JSHandle<ChangeListener> handleChangeListenerArr = JSHandle<ChangeListener>::Cast(weakVector);
267 EXPECT_TRUE(*handleChangeListenerArr != nullptr);
268 EXPECT_EQ(handleChangeListenerArr->Get(0).GetInt(), 0);
269 // the value is the weakRef of objValue
270 EXPECT_EQ(handleChangeListenerArr->Get(1).GetTaggedObject(), objValue.GetTaggedWeakRef());
271 EXPECT_TRUE(handleChangeListenerArr->Get(2).IsUndefined());
272 }
273 } // namespace panda::test
274