14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#include "ecmascript/ic/proto_change_details.h"
174514f5e3Sopenharmony_ci#include "ecmascript/global_env.h"
184514f5e3Sopenharmony_ci#include "ecmascript/tagged_array.h"
194514f5e3Sopenharmony_ci#include "ecmascript/tests/test_helper.h"
204514f5e3Sopenharmony_ci#include "ecmascript/weak_vector.h"
214514f5e3Sopenharmony_ci
224514f5e3Sopenharmony_ciusing namespace panda::ecmascript;
234514f5e3Sopenharmony_ci
244514f5e3Sopenharmony_cinamespace panda::test {
254514f5e3Sopenharmony_ciclass ProtoChangeDetailsTest : public testing::Test {
264514f5e3Sopenharmony_cipublic:
274514f5e3Sopenharmony_ci    static void SetUpTestCase()
284514f5e3Sopenharmony_ci    {
294514f5e3Sopenharmony_ci        GTEST_LOG_(INFO) << "SetUpTestCase";
304514f5e3Sopenharmony_ci    }
314514f5e3Sopenharmony_ci
324514f5e3Sopenharmony_ci    static void TearDownTestCase()
334514f5e3Sopenharmony_ci    {
344514f5e3Sopenharmony_ci        GTEST_LOG_(INFO) << "TearDownCase";
354514f5e3Sopenharmony_ci    }
364514f5e3Sopenharmony_ci
374514f5e3Sopenharmony_ci    void SetUp() override
384514f5e3Sopenharmony_ci    {
394514f5e3Sopenharmony_ci        TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
404514f5e3Sopenharmony_ci    }
414514f5e3Sopenharmony_ci
424514f5e3Sopenharmony_ci    void TearDown() override
434514f5e3Sopenharmony_ci    {
444514f5e3Sopenharmony_ci        TestHelper::DestroyEcmaVMWithScope(instance, scope);
454514f5e3Sopenharmony_ci    }
464514f5e3Sopenharmony_ci
474514f5e3Sopenharmony_ci    EcmaVM *instance {nullptr};
484514f5e3Sopenharmony_ci    EcmaHandleScope *scope {nullptr};
494514f5e3Sopenharmony_ci    JSThread *thread {nullptr};
504514f5e3Sopenharmony_ci};
514514f5e3Sopenharmony_ci
524514f5e3Sopenharmony_ci/**
534514f5e3Sopenharmony_ci * @tc.name: SetBitField
544514f5e3Sopenharmony_ci * @tc.desc: Check whether the result returned through "GetBitField" function is within expectations.
554514f5e3Sopenharmony_ci * @tc.type: FUNC
564514f5e3Sopenharmony_ci * @tc.require:
574514f5e3Sopenharmony_ci */
584514f5e3Sopenharmony_ciHWTEST_F_L0(ProtoChangeDetailsTest, SetBitField)
594514f5e3Sopenharmony_ci{
604514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
614514f5e3Sopenharmony_ci    JSHandle<ProtoChangeMarker> handleProtoChangeMarker = factory->NewProtoChangeMarker();
624514f5e3Sopenharmony_ci
634514f5e3Sopenharmony_ci    handleProtoChangeMarker->SetBitField(true);
644514f5e3Sopenharmony_ci    EXPECT_TRUE(handleProtoChangeMarker->GetBitField());
654514f5e3Sopenharmony_ci
664514f5e3Sopenharmony_ci    handleProtoChangeMarker->SetBitField(false);
674514f5e3Sopenharmony_ci    EXPECT_FALSE(handleProtoChangeMarker->GetBitField());
684514f5e3Sopenharmony_ci}
694514f5e3Sopenharmony_ci
704514f5e3Sopenharmony_ci/**
714514f5e3Sopenharmony_ci * @tc.name: SetHasChanged
724514f5e3Sopenharmony_ci * @tc.desc: Check whether the result returned through "GetHasChanged" function is within expectations.
734514f5e3Sopenharmony_ci * @tc.type: FUNC
744514f5e3Sopenharmony_ci * @tc.require:
754514f5e3Sopenharmony_ci */
764514f5e3Sopenharmony_ciHWTEST_F_L0(ProtoChangeDetailsTest, SetHasChanged)
774514f5e3Sopenharmony_ci{
784514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
794514f5e3Sopenharmony_ci    JSHandle<ProtoChangeMarker> handleProtoChangeMarker = factory->NewProtoChangeMarker();
804514f5e3Sopenharmony_ci
814514f5e3Sopenharmony_ci    handleProtoChangeMarker->SetHasChanged(true);
824514f5e3Sopenharmony_ci    EXPECT_TRUE(handleProtoChangeMarker->GetHasChanged());
834514f5e3Sopenharmony_ci
844514f5e3Sopenharmony_ci    handleProtoChangeMarker->SetHasChanged(false);
854514f5e3Sopenharmony_ci    EXPECT_FALSE(handleProtoChangeMarker->GetHasChanged());
864514f5e3Sopenharmony_ci}
874514f5e3Sopenharmony_ci
884514f5e3Sopenharmony_ci/**
894514f5e3Sopenharmony_ci * @tc.name: SetChangeListener
904514f5e3Sopenharmony_ci * @tc.desc: Check whether the result returned through "GetChangeListener" function is within expectations.
914514f5e3Sopenharmony_ci * @tc.type: FUNC
924514f5e3Sopenharmony_ci * @tc.require:
934514f5e3Sopenharmony_ci */
944514f5e3Sopenharmony_ciHWTEST_F_L0(ProtoChangeDetailsTest, SetChangeListener)
954514f5e3Sopenharmony_ci{
964514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
974514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(1));
984514f5e3Sopenharmony_ci
994514f5e3Sopenharmony_ci    uint32_t weakVectorCapacity = 100;
1004514f5e3Sopenharmony_ci    JSHandle<WeakVector> weakVector = WeakVector::Create(thread, weakVectorCapacity);
1014514f5e3Sopenharmony_ci    JSHandle<ChangeListener> handleChangeListener = JSHandle<ChangeListener>::Cast(weakVector);
1024514f5e3Sopenharmony_ci    JSHandle<ProtoChangeDetails> handleChangeDetails = factory->NewProtoChangeDetails();
1034514f5e3Sopenharmony_ci
1044514f5e3Sopenharmony_ci    handleChangeDetails->SetChangeListener(thread, handleValue.GetTaggedValue());
1054514f5e3Sopenharmony_ci    EXPECT_EQ(handleChangeDetails->GetChangeListener().GetInt(), 1);
1064514f5e3Sopenharmony_ci    handleChangeDetails->SetChangeListener(thread, handleChangeListener.GetTaggedValue());
1074514f5e3Sopenharmony_ci    EXPECT_EQ(handleChangeDetails->GetChangeListener(), handleChangeListener.GetTaggedValue());
1084514f5e3Sopenharmony_ci}
1094514f5e3Sopenharmony_ci
1104514f5e3Sopenharmony_ci/**
1114514f5e3Sopenharmony_ci * @tc.name: SetRegisterIndex
1124514f5e3Sopenharmony_ci * @tc.desc: Check whether the result returned through "GetRegisterIndex" function is within expectations.
1134514f5e3Sopenharmony_ci * @tc.type: FUNC
1144514f5e3Sopenharmony_ci * @tc.require:
1154514f5e3Sopenharmony_ci */
1164514f5e3Sopenharmony_ciHWTEST_F_L0(ProtoChangeDetailsTest, SetRegisterIndex)
1174514f5e3Sopenharmony_ci{
1184514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1194514f5e3Sopenharmony_ci    JSHandle<ProtoChangeDetails> handleChangeDetails = factory->NewProtoChangeDetails();
1204514f5e3Sopenharmony_ci
1214514f5e3Sopenharmony_ci    handleChangeDetails->SetRegisterIndex(static_cast<uint32_t>(1));
1224514f5e3Sopenharmony_ci    EXPECT_EQ(handleChangeDetails->GetRegisterIndex(), 1U);
1234514f5e3Sopenharmony_ci}
1244514f5e3Sopenharmony_ci
1254514f5e3Sopenharmony_ci/**
1264514f5e3Sopenharmony_ci * @tc.name: Add_001
1274514f5e3Sopenharmony_ci * @tc.desc: Create a weakvector object with a length of ten,Call the "pushback" function to set the value of the
1284514f5e3Sopenharmony_ci *           vector.the vector is not fully set,convert the weakvector object into a ChangeListener object.In this case,
1294514f5e3Sopenharmony_ci *           call the "add" function to add a jshclass object. The added jshclass object will create and get weakref and
1304514f5e3Sopenharmony_ci *           return the location of the added object.
1314514f5e3Sopenharmony_ci * @tc.type: FUNC
1324514f5e3Sopenharmony_ci * @tc.require:
1334514f5e3Sopenharmony_ci */
1344514f5e3Sopenharmony_ciHWTEST_F_L0(ProtoChangeDetailsTest, Add_001)
1354514f5e3Sopenharmony_ci{
1364514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1374514f5e3Sopenharmony_ci    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1384514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
1394514f5e3Sopenharmony_ci    JSHandle<JSObject> handleObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
1404514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> objClassVal(thread, handleObj->GetJSHClass());
1414514f5e3Sopenharmony_ci    uint32_t weakVectorCapacity = 10;
1424514f5e3Sopenharmony_ci    uint32_t index = 2;
1434514f5e3Sopenharmony_ci    JSHandle<WeakVector> weakVector = WeakVector::Create(thread, weakVectorCapacity);
1444514f5e3Sopenharmony_ci    for (int i = 0; i < 9; i++) {
1454514f5e3Sopenharmony_ci        weakVector->PushBack(thread, JSTaggedValue(i));
1464514f5e3Sopenharmony_ci    } // weakVector is not full
1474514f5e3Sopenharmony_ci    JSHandle<ChangeListener> handleChangeListenerArr = JSHandle<ChangeListener>::Cast(weakVector);
1484514f5e3Sopenharmony_ci    JSHandle<ChangeListener> resultListenerArray =
1494514f5e3Sopenharmony_ci        ChangeListener::Add(thread, handleChangeListenerArr, JSHandle<JSHClass>(objClassVal), &index);
1504514f5e3Sopenharmony_ci    EXPECT_EQ(index, 9U);
1514514f5e3Sopenharmony_ci    JSTaggedValue weakRefValue(objClassVal.GetTaggedValue());
1524514f5e3Sopenharmony_ci    weakRefValue.CreateWeakRef();
1534514f5e3Sopenharmony_ci    EXPECT_EQ(resultListenerArray->Get(index).GetTaggedObject(), weakRefValue.GetTaggedWeakRef());
1544514f5e3Sopenharmony_ci}
1554514f5e3Sopenharmony_ci
1564514f5e3Sopenharmony_ci/**
1574514f5e3Sopenharmony_ci * @tc.name: Add_002
1584514f5e3Sopenharmony_ci * @tc.desc: Create a weakvector object with a length of ten,Call the "pushback" function to set the value of the
1594514f5e3Sopenharmony_ci *           vector the vector is fully set but exist hole,convert the weakvector object into a ChangeListener object
1604514f5e3Sopenharmony_ci *           in this case call the "add" function to add a jshclass object. The added jshclass object will create and
1614514f5e3Sopenharmony_ci *           get weakref and return the location of the added object.
1624514f5e3Sopenharmony_ci * @tc.type: FUNC
1634514f5e3Sopenharmony_ci * @tc.require:
1644514f5e3Sopenharmony_ci */
1654514f5e3Sopenharmony_ciHWTEST_F_L0(ProtoChangeDetailsTest, Add_002)
1664514f5e3Sopenharmony_ci{
1674514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1684514f5e3Sopenharmony_ci    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
1694514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
1704514f5e3Sopenharmony_ci    JSHandle<JSObject> handleObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
1714514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> objClassVal(thread, handleObj->GetJSHClass());
1724514f5e3Sopenharmony_ci    uint32_t weakVectorCapacity = 10;
1734514f5e3Sopenharmony_ci    uint32_t index = 2;
1744514f5e3Sopenharmony_ci    JSHandle<WeakVector> weakVector = WeakVector::Create(thread, weakVectorCapacity);
1754514f5e3Sopenharmony_ci    for (int i = 0; i < 10; i++) {
1764514f5e3Sopenharmony_ci        weakVector->PushBack(thread, JSTaggedValue(i));
1774514f5e3Sopenharmony_ci    }
1784514f5e3Sopenharmony_ci    JSHandle<ChangeListener> handleChangeListenerArr = JSHandle<ChangeListener>::Cast(weakVector);
1794514f5e3Sopenharmony_ci    // weakVector exist hole
1804514f5e3Sopenharmony_ci    weakVector->Delete(thread, 1); // delete in one
1814514f5e3Sopenharmony_ci    JSHandle<ChangeListener> resultListenerArray =
1824514f5e3Sopenharmony_ci    ChangeListener::Add(thread, handleChangeListenerArr, JSHandle<JSHClass>(objClassVal), &index);
1834514f5e3Sopenharmony_ci    EXPECT_EQ(index, 1U);
1844514f5e3Sopenharmony_ci    JSTaggedValue weakRefValue(objClassVal.GetTaggedValue());
1854514f5e3Sopenharmony_ci    weakRefValue.CreateWeakRef();
1864514f5e3Sopenharmony_ci    EXPECT_EQ(resultListenerArray->Get(index).GetTaggedObject(), weakRefValue.GetTaggedWeakRef());
1874514f5e3Sopenharmony_ci}
1884514f5e3Sopenharmony_ci
1894514f5e3Sopenharmony_ci/**
1904514f5e3Sopenharmony_ci * @tc.name: Add_003
1914514f5e3Sopenharmony_ci * @tc.desc: Create a weakvector object with a length of ten,Call the "pushback" function to set the value of the
1924514f5e3Sopenharmony_ci *           vector the vector is fully set and not exist hole,convert the weakvector object into a ChangeListener
1934514f5e3Sopenharmony_ci *           object.in this case call the "add" function increase the length to add the jshclass object. The added
1944514f5e3Sopenharmony_ci *           jshclass object will create and get weakref and return the location of the added object.
1954514f5e3Sopenharmony_ci * @tc.type: FUNC
1964514f5e3Sopenharmony_ci * @tc.require:
1974514f5e3Sopenharmony_ci */
1984514f5e3Sopenharmony_ciHWTEST_F_L0(ProtoChangeDetailsTest, Add_003)
1994514f5e3Sopenharmony_ci{
2004514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2014514f5e3Sopenharmony_ci    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
2024514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
2034514f5e3Sopenharmony_ci    JSHandle<JSObject> handleObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
2044514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> objClassVal(thread, handleObj->GetJSHClass());
2054514f5e3Sopenharmony_ci    uint32_t weakVectorCapacity = 10;
2064514f5e3Sopenharmony_ci    uint32_t index = 2;
2074514f5e3Sopenharmony_ci    JSHandle<WeakVector> weakVector = WeakVector::Create(thread, weakVectorCapacity);
2084514f5e3Sopenharmony_ci    for (int i = 0; i < 10; i++) {
2094514f5e3Sopenharmony_ci        weakVector->PushBack(thread, JSTaggedValue(i));
2104514f5e3Sopenharmony_ci    }
2114514f5e3Sopenharmony_ci    JSHandle<ChangeListener> handleChangeListenerArr = JSHandle<ChangeListener>::Cast(weakVector);
2124514f5e3Sopenharmony_ci    // weakVector is full and no hole exists.
2134514f5e3Sopenharmony_ci    JSHandle<ChangeListener> resultListenerArray =
2144514f5e3Sopenharmony_ci    ChangeListener::Add(thread, handleChangeListenerArr, JSHandle<JSHClass>(objClassVal), &index);
2154514f5e3Sopenharmony_ci    EXPECT_EQ(index, 10U);
2164514f5e3Sopenharmony_ci    JSTaggedValue weakRefValue(objClassVal.GetTaggedValue());
2174514f5e3Sopenharmony_ci    weakRefValue.CreateWeakRef();
2184514f5e3Sopenharmony_ci    EXPECT_EQ(resultListenerArray->Get(index).GetTaggedObject(), weakRefValue.GetTaggedWeakRef());
2194514f5e3Sopenharmony_ci}
2204514f5e3Sopenharmony_ci
2214514f5e3Sopenharmony_ci/**
2224514f5e3Sopenharmony_ci * @tc.name: CheckHole
2234514f5e3Sopenharmony_ci * @tc.desc: Create a weakvector object with a length of ten,Call the "pushback" function to set the value of the
2244514f5e3Sopenharmony_ci *           vector the vector is fully set,convert the weakvector object into a ChangeListener object.ChangeListener
2254514f5e3Sopenharmony_ci *           object call the "CheckHole" function to check whether there is a hole. If there is, return the location
2264514f5e3Sopenharmony_ci *           of the hole If not, return the maximum value.
2274514f5e3Sopenharmony_ci * @tc.type: FUNC
2284514f5e3Sopenharmony_ci * @tc.require:
2294514f5e3Sopenharmony_ci */
2304514f5e3Sopenharmony_ciHWTEST_F_L0(ProtoChangeDetailsTest, CheckHole)
2314514f5e3Sopenharmony_ci{
2324514f5e3Sopenharmony_ci    uint32_t weakVectorCapacity = 10;
2334514f5e3Sopenharmony_ci    JSHandle<WeakVector> weakVector = WeakVector::Create(thread, weakVectorCapacity);
2344514f5e3Sopenharmony_ci    for (int i = 0; i < 10; i++) {
2354514f5e3Sopenharmony_ci        weakVector->PushBack(thread, JSTaggedValue(i)); // Set Value and End
2364514f5e3Sopenharmony_ci    }
2374514f5e3Sopenharmony_ci    JSHandle<ChangeListener> handleChangeListenerArr = JSHandle<ChangeListener>::Cast(weakVector);
2384514f5e3Sopenharmony_ci    EXPECT_EQ(ChangeListener::CheckHole(handleChangeListenerArr), TaggedArray::MAX_ARRAY_INDEX);
2394514f5e3Sopenharmony_ci    weakVector->Delete(thread, 1);
2404514f5e3Sopenharmony_ci    EXPECT_EQ(ChangeListener::CheckHole(handleChangeListenerArr), 1U);
2414514f5e3Sopenharmony_ci}
2424514f5e3Sopenharmony_ci
2434514f5e3Sopenharmony_ci/**
2444514f5e3Sopenharmony_ci * @tc.name: Get
2454514f5e3Sopenharmony_ci * @tc.desc: Create a weakvector object with a length of three,Call the "pushback" function to set the value of the
2464514f5e3Sopenharmony_ci *           vector the vector is fully set,convert the weakvector object into a ChangeListener object.check whether
2474514f5e3Sopenharmony_ci *           the return value of calling "Get" function is the same as the value set by calling the "Set" function.
2484514f5e3Sopenharmony_ci * @tc.type: FUNC
2494514f5e3Sopenharmony_ci * @tc.require:
2504514f5e3Sopenharmony_ci */
2514514f5e3Sopenharmony_ciHWTEST_F_L0(ProtoChangeDetailsTest, Get)
2524514f5e3Sopenharmony_ci{
2534514f5e3Sopenharmony_ci    uint32_t weakVectorCapacity = 3;
2544514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
2554514f5e3Sopenharmony_ci    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
2564514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> objFun = env->GetObjectFunction();
2574514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> handleObj(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun));
2584514f5e3Sopenharmony_ci    JSHandle<WeakVector> weakVector = WeakVector::Create(thread, weakVectorCapacity);
2594514f5e3Sopenharmony_ci    // create weakref
2604514f5e3Sopenharmony_ci    JSTaggedValue objValue(handleObj.GetTaggedValue());
2614514f5e3Sopenharmony_ci    objValue.CreateWeakRef();
2624514f5e3Sopenharmony_ci    // set value for vector
2634514f5e3Sopenharmony_ci    weakVector->Set(thread, 0, JSTaggedValue(0));
2644514f5e3Sopenharmony_ci    weakVector->Set(thread, 1, objValue);
2654514f5e3Sopenharmony_ci    weakVector->Set(thread, 2, JSTaggedValue::Undefined());
2664514f5e3Sopenharmony_ci    JSHandle<ChangeListener> handleChangeListenerArr = JSHandle<ChangeListener>::Cast(weakVector);
2674514f5e3Sopenharmony_ci    EXPECT_TRUE(*handleChangeListenerArr != nullptr);
2684514f5e3Sopenharmony_ci    EXPECT_EQ(handleChangeListenerArr->Get(0).GetInt(), 0);
2694514f5e3Sopenharmony_ci    // the value is the weakRef of objValue
2704514f5e3Sopenharmony_ci    EXPECT_EQ(handleChangeListenerArr->Get(1).GetTaggedObject(), objValue.GetTaggedWeakRef());
2714514f5e3Sopenharmony_ci    EXPECT_TRUE(handleChangeListenerArr->Get(2).IsUndefined());
2724514f5e3Sopenharmony_ci}
2734514f5e3Sopenharmony_ci} // namespace panda::test
274