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