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 20using namespace panda; 21using namespace panda::ecmascript; 22 23namespace panda::test { 24class 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 */ 35HWTEST_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 */ 52HWTEST_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(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 */ 77HWTEST_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(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 */ 116HWTEST_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(i).IsHole()); 140 } 141 for (uint32_t i = pushWeakVectorCapacity; i < weakVectorCapacity; i++) { 142 EXPECT_EQ(weakVector->Get(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 */ 153HWTEST_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(i).IsHole()); 174 } 175 EXPECT_FALSE(weakVector->Empty()); 176 EXPECT_EQ(weakVector->GetCapacity(), weakVectorCapacity); 177} 178} // namespace panda::test