1 /*
2 * Copyright (c) 2022 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/weak_vector.h"
17 #include "ecmascript/global_env.h"
18 #include "ecmascript/tests/test_helper.h"
19
20 using namespace panda;
21 using namespace panda::ecmascript;
22
23 namespace panda::test {
24 class WeakVectorTest : public BaseTestWithScope<false> {
25 };
26
27 /**
28 * @tc.name: Create
29 * @tc.desc: Check whether the returned value through "Create" function is within expectations by "GetEnd"
30 * function and "Empty" function. convert to tagedarray, and check whether the length attribute
31 * meets the expectation.
32 * @tc.type: FUNC
33 * @tc.require:
34 */
HWTEST_F_L0(WeakVectorTest,Create)35 HWTEST_F_L0(WeakVectorTest, Create)
36 {
37 uint32_t weakVectorCapacity = 100;
38 JSHandle<WeakVector> weakVector = WeakVector::Create(thread, weakVectorCapacity);
39 EXPECT_TRUE(*weakVector != nullptr);
40 JSHandle<TaggedArray> weakVectArr(weakVector);
41 EXPECT_EQ(weakVector->GetEnd(), 0U);
42 EXPECT_TRUE(weakVector->Empty());
43 EXPECT_EQ(weakVectArr->GetLength(), weakVectorCapacity + 1);
44 }
45
46 /**
47 * @tc.name: SetAndGet
48 * @tc.desc: Check whether each value in the vector container is the same as the value of set by "set" function.
49 * @tc.type: FUNC
50 * @tc.require:
51 */
HWTEST_F_L0(WeakVectorTest,SetAndGet)52 HWTEST_F_L0(WeakVectorTest, SetAndGet)
53 {
54 uint32_t weakVectorCapacity = 100;
55 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
56 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
57 JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
58 JSHandle<WeakVector> weakVector = WeakVector::Create(thread, weakVectorCapacity);
59
60 JSHandle<JSObject> weakObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
61 JSHandle<JSTaggedValue> weakObjclassVal(thread, weakObj->GetJSHClass());
62 JSTaggedValue weakValue = JSTaggedValue(weakObjclassVal.GetTaggedValue().CreateAndGetWeakRef());
63 // set weak value
64 for (uint32_t i = 0; i < weakVectorCapacity; i++) {
65 weakVector->Set(thread, i, weakValue);
66 EXPECT_EQ(weakVector->Get(thread, i), weakValue);
67 }
68 }
69
70 /**
71 * @tc.name: Grow
72 * @tc.desc: Create a weak vector with a certain length through the "Create" function, and then expand the weak vector
73 * with the "Grow" function to increase its length.
74 * @tc.type: FUNC
75 * @tc.require:
76 */
HWTEST_F_L0(WeakVectorTest,Grow)77 HWTEST_F_L0(WeakVectorTest, Grow)
78 {
79 thread->GetEcmaVM()->SetEnableForceGC(false); // turn off gc
80 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
81 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
82 JSHandle<JSTaggedValue> objFun = env->GetStringFunction();
83
84 JSHandle<JSObject> weakObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
85 JSHandle<JSTaggedValue> weakObjclassVal(thread, weakObj->GetJSHClass());
86 JSTaggedValue weakValue = JSTaggedValue(weakObjclassVal.GetTaggedValue().CreateAndGetWeakRef());
87 // test growing vector with null value
88 uint32_t oldWeakVectorCapacity = 0;
89 uint32_t newWeakVectorCapacity = 100;
90 JSHandle<WeakVector> oldWeakVector = WeakVector::Create(thread, oldWeakVectorCapacity);
91 JSHandle<WeakVector> newWeakVector = oldWeakVector->Grow(thread, oldWeakVector, newWeakVectorCapacity);
92 EXPECT_EQ(newWeakVector->GetCapacity(), newWeakVectorCapacity);
93 EXPECT_TRUE(newWeakVector->Empty());
94 // test growing vector with no null value
95 oldWeakVectorCapacity = 100;
96 newWeakVectorCapacity = 200;
97 for (uint32_t i = 0; i < oldWeakVectorCapacity; i++) {
98 newWeakVector->Set(thread, i, weakValue);
99 }
100 newWeakVector = newWeakVector->Grow(thread, newWeakVector, newWeakVectorCapacity);
101 EXPECT_EQ(newWeakVector->GetCapacity(), newWeakVectorCapacity);
102 for (uint32_t i = 0; i < oldWeakVectorCapacity; i++) {
103 EXPECT_EQ(newWeakVector->Get(thread, i), weakValue);
104 }
105 EXPECT_EQ(newWeakVector->GetEnd(), 0U);
106 thread->GetEcmaVM()->SetEnableForceGC(true); // turn on gc
107 }
108
109 /**
110 * @tc.name: PushBack
111 * @tc.desc: Change the value in the weak vector through "pushback" function,and compare whether the original value of
112 * the weak vector and the pushback value are the same in the pushback position.
113 * @tc.type: FUNC
114 * @tc.require:
115 */
HWTEST_F_L0(WeakVectorTest,PushBack)116 HWTEST_F_L0(WeakVectorTest, PushBack)
117 {
118 uint32_t weakVectorCapacity = 100;
119 uint32_t pushWeakVectorCapacity = weakVectorCapacity >> 2; // 2: means half value
120 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
121 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
122 JSHandle<JSTaggedValue> objFun = env->GetPromiseFunction();
123 JSHandle<WeakVector> weakVector = WeakVector::Create(thread, weakVectorCapacity);
124
125 JSHandle<JSObject> weakObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
126 JSHandle<JSTaggedValue> weakObjclassVal(thread, weakObj->GetJSHClass());
127 JSTaggedValue weakValue = JSTaggedValue(weakObjclassVal.GetTaggedValue().CreateAndGetWeakRef());
128 // fill the value into the vector
129 for (uint32_t i = 0; i < weakVectorCapacity; i++) {
130 weakVector->Set(thread, i, weakValue);
131 }
132 // push the value into the vector and reset end
133 for (uint32_t i = 0; i < pushWeakVectorCapacity; i++) {
134 weakVector->PushBack(thread, JSTaggedValue::Hole());
135 }
136 EXPECT_EQ(weakVector->GetEnd(), pushWeakVectorCapacity);
137
138 for (uint32_t i = 0; i < pushWeakVectorCapacity; i++) {
139 EXPECT_TRUE(weakVector->Get(thread, i).IsHole());
140 }
141 for (uint32_t i = pushWeakVectorCapacity; i < weakVectorCapacity; i++) {
142 EXPECT_EQ(weakVector->Get(thread, i), weakValue);
143 }
144 }
145
146 /**
147 * @tc.name: Delete
148 * @tc.desc: Check whether the value in the vector container is hole when deleted, and whether the container
149 * is not empty when all are deleted by "delete" function.
150 * @tc.type: FUNC
151 * @tc.require:
152 */
HWTEST_F_L0(WeakVectorTest,Delete)153 HWTEST_F_L0(WeakVectorTest, Delete)
154 {
155 uint32_t weakVectorCapacity = 100;
156 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
157 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
158 JSHandle<JSTaggedValue> objFun = env->GetPromiseFunction();
159 JSHandle<WeakVector> weakVector = WeakVector::Create(thread, weakVectorCapacity);
160
161 JSHandle<JSObject> weakObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
162 JSHandle<JSTaggedValue> weakObjclassVal(thread, weakObj->GetJSHClass());
163 JSTaggedValue weakValue = JSTaggedValue(weakObjclassVal.GetTaggedValue().CreateAndGetWeakRef());
164
165 for (uint32_t i = 0; i < weakVectorCapacity; i++) {
166 weakVector->PushBack(thread, weakValue);
167 }
168 EXPECT_TRUE(weakVector->Full());
169 EXPECT_FALSE(weakVector->Delete(thread, weakVectorCapacity));
170
171 for (uint32_t i = 0; i < weakVectorCapacity; i++) {
172 EXPECT_TRUE(weakVector->Delete(thread, i));
173 EXPECT_TRUE(weakVector->Get(thread, i).IsHole());
174 }
175 EXPECT_FALSE(weakVector->Empty());
176 EXPECT_EQ(weakVector->GetCapacity(), weakVectorCapacity);
177 }
178 } // namespace panda::test