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 22using namespace panda::ecmascript; 23 24namespace panda::test { 25class ProtoChangeDetailsTest : public testing::Test { 26public: 27 static void SetUpTestCase() 28 { 29 GTEST_LOG_(INFO) << "SetUpTestCase"; 30 } 31 32 static void TearDownTestCase() 33 { 34 GTEST_LOG_(INFO) << "TearDownCase"; 35 } 36 37 void SetUp() override 38 { 39 TestHelper::CreateEcmaVMWithScope(instance, thread, scope); 40 } 41 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 */ 58HWTEST_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 */ 76HWTEST_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 */ 94HWTEST_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 */ 116HWTEST_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 */ 134HWTEST_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 */ 165HWTEST_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 */ 198HWTEST_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 */ 230HWTEST_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 */ 251HWTEST_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