14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2022 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/layout_info-inl.h" 174514f5e3Sopenharmony_ci#include "ecmascript/property_attributes.h" 184514f5e3Sopenharmony_ci#include "ecmascript/tests/test_helper.h" 194514f5e3Sopenharmony_ci 204514f5e3Sopenharmony_ciusing namespace panda::ecmascript; 214514f5e3Sopenharmony_ci 224514f5e3Sopenharmony_cinamespace panda::test { 234514f5e3Sopenharmony_ciclass LayoutInfoTest : public BaseTestWithScope<false> { 244514f5e3Sopenharmony_ci}; 254514f5e3Sopenharmony_ci 264514f5e3Sopenharmony_ciHWTEST_F_L0(LayoutInfoTest, SetNumberOfElements) 274514f5e3Sopenharmony_ci{ 284514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 294514f5e3Sopenharmony_ci int32_t infoLength = 2; // 2: len 304514f5e3Sopenharmony_ci JSHandle<LayoutInfo> layoutInfoHandle = factory->CreateLayoutInfo(infoLength); 314514f5e3Sopenharmony_ci EXPECT_TRUE(*layoutInfoHandle != nullptr); 324514f5e3Sopenharmony_ci 334514f5e3Sopenharmony_ci layoutInfoHandle->SetNumberOfElements(thread, 100); 344514f5e3Sopenharmony_ci EXPECT_EQ(layoutInfoHandle->NumberOfElements(), 100); 354514f5e3Sopenharmony_ci} 364514f5e3Sopenharmony_ci 374514f5e3Sopenharmony_ciHWTEST_F_L0(LayoutInfoTest, SetPropertyInit) 384514f5e3Sopenharmony_ci{ 394514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 404514f5e3Sopenharmony_ci int32_t infoLength = 3; 414514f5e3Sopenharmony_ci PropertyAttributes defaultAttr = PropertyAttributes::Default(); 424514f5e3Sopenharmony_ci defaultAttr.SetNormalAttr(infoLength); 434514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> key(factory->NewFromASCII("key")); 444514f5e3Sopenharmony_ci JSHandle<LayoutInfo> layoutInfoHandle = factory->CreateLayoutInfo(infoLength); 454514f5e3Sopenharmony_ci EXPECT_TRUE(*layoutInfoHandle != nullptr); 464514f5e3Sopenharmony_ci 474514f5e3Sopenharmony_ci layoutInfoHandle->SetPropertyInit(thread, 0, key.GetTaggedValue(), defaultAttr); 484514f5e3Sopenharmony_ci EXPECT_EQ(layoutInfoHandle->GetKey(0), key.GetTaggedValue()); 494514f5e3Sopenharmony_ci EXPECT_EQ(layoutInfoHandle->GetAttr(0).GetNormalAttr(), static_cast<uint32_t>(infoLength)); 504514f5e3Sopenharmony_ci} 514514f5e3Sopenharmony_ci 524514f5e3Sopenharmony_ciHWTEST_F_L0(LayoutInfoTest, SetSortedIndex) 534514f5e3Sopenharmony_ci{ 544514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 554514f5e3Sopenharmony_ci int32_t infoLength = 5; 564514f5e3Sopenharmony_ci PropertyAttributes defaultAttr = PropertyAttributes::Default(); 574514f5e3Sopenharmony_ci defaultAttr.SetNormalAttr(infoLength); 584514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> key1(factory->NewFromASCII("hello")); 594514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> key2(factory->NewFromASCII("world")); 604514f5e3Sopenharmony_ci JSHandle<LayoutInfo> layoutInfoHandle = factory->CreateLayoutInfo(infoLength); 614514f5e3Sopenharmony_ci EXPECT_TRUE(*layoutInfoHandle != nullptr); 624514f5e3Sopenharmony_ci 634514f5e3Sopenharmony_ci layoutInfoHandle->SetPropertyInit(thread, 0, key1.GetTaggedValue(), defaultAttr); 644514f5e3Sopenharmony_ci layoutInfoHandle->SetPropertyInit(thread, 1, key2.GetTaggedValue(), defaultAttr); 654514f5e3Sopenharmony_ci layoutInfoHandle->SetSortedIndex(thread, 0, infoLength - 4); 664514f5e3Sopenharmony_ci EXPECT_EQ(layoutInfoHandle->GetSortedIndex(0), 1U); 674514f5e3Sopenharmony_ci EXPECT_EQ(layoutInfoHandle->GetSortedKey(0), key2.GetTaggedValue()); 684514f5e3Sopenharmony_ci} 694514f5e3Sopenharmony_ci 704514f5e3Sopenharmony_ciHWTEST_F_L0(LayoutInfoTest, FindElementWithCache) 714514f5e3Sopenharmony_ci{ 724514f5e3Sopenharmony_ci int infoLength = 5; 734514f5e3Sopenharmony_ci int newPropertiesLength = 11; 744514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 754514f5e3Sopenharmony_ci PropertyAttributes defaultAttr = PropertyAttributes::Default(); 764514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> key1(factory->NewFromASCII("1")); 774514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> key4(factory->NewFromASCII("4")); 784514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> key5(factory->NewFromASCII("5")); 794514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> key10(factory->NewFromASCII("10")); 804514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> key11(factory->NewFromASCII("11")); 814514f5e3Sopenharmony_ci JSHandle<LayoutInfo> layoutInfoHandle = factory->CreateLayoutInfo(infoLength); 824514f5e3Sopenharmony_ci EXPECT_TRUE(*layoutInfoHandle != nullptr); 834514f5e3Sopenharmony_ci for (int i = 0; i < infoLength; i++) { 844514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> elements(thread, JSTaggedValue(i)); 854514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> elementsKey(JSTaggedValue::ToString(thread, elements)); 864514f5e3Sopenharmony_ci defaultAttr.SetOffset(i); 874514f5e3Sopenharmony_ci layoutInfoHandle->AddKey(thread, i, elementsKey.GetTaggedValue(), defaultAttr); 884514f5e3Sopenharmony_ci } 894514f5e3Sopenharmony_ci int propertiesNumber = layoutInfoHandle->NumberOfElements(); 904514f5e3Sopenharmony_ci int result = 0; 914514f5e3Sopenharmony_ci result = layoutInfoHandle->FindElementWithCache(thread, nullptr, key1.GetTaggedValue(), propertiesNumber); 924514f5e3Sopenharmony_ci EXPECT_EQ(result, 1); // 1: Index corresponding to key1 934514f5e3Sopenharmony_ci result = layoutInfoHandle->FindElementWithCache(thread, nullptr, key5.GetTaggedValue(), propertiesNumber); 944514f5e3Sopenharmony_ci EXPECT_EQ(result, -1); // -1: not find 954514f5e3Sopenharmony_ci // extend layoutInfo 964514f5e3Sopenharmony_ci JSHandle<LayoutInfo> newLayoutInfo = factory->ExtendLayoutInfo(layoutInfoHandle, newPropertiesLength); 974514f5e3Sopenharmony_ci for (int i = 5; i < newPropertiesLength; i++) { 984514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> elements(thread, JSTaggedValue(i)); 994514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> elementsKey(JSTaggedValue::ToString(thread, elements)); 1004514f5e3Sopenharmony_ci defaultAttr.SetOffset(i); 1014514f5e3Sopenharmony_ci newLayoutInfo->AddKey(thread, i, elementsKey.GetTaggedValue(), defaultAttr); 1024514f5e3Sopenharmony_ci } 1034514f5e3Sopenharmony_ci result = newLayoutInfo->FindElementWithCache(thread, nullptr, key4.GetTaggedValue(), newPropertiesLength); 1044514f5e3Sopenharmony_ci EXPECT_EQ(result, 4); // 4: Index corresponding to key4 1054514f5e3Sopenharmony_ci result = newLayoutInfo->FindElementWithCache(thread, nullptr, key10.GetTaggedValue(), newPropertiesLength); 1064514f5e3Sopenharmony_ci EXPECT_EQ(result, 10); // 10: Index corresponding to key10 1074514f5e3Sopenharmony_ci result = newLayoutInfo->FindElementWithCache(thread, nullptr, key5.GetTaggedValue(), newPropertiesLength); 1084514f5e3Sopenharmony_ci EXPECT_EQ(result, 5); // 5: Index corresponding to key5 1094514f5e3Sopenharmony_ci result = newLayoutInfo->FindElementWithCache(thread, nullptr, key11.GetTaggedValue(), newPropertiesLength); 1104514f5e3Sopenharmony_ci EXPECT_EQ(result, -1); // -1: not find 1114514f5e3Sopenharmony_ci} 1124514f5e3Sopenharmony_ci 1134514f5e3Sopenharmony_civoid GetAllKeysCommon(JSThread *thread, bool enumKeys = false) 1144514f5e3Sopenharmony_ci{ 1154514f5e3Sopenharmony_ci int infoLength = 5; 1164514f5e3Sopenharmony_ci ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 1174514f5e3Sopenharmony_ci PropertyAttributes defaultAttr = PropertyAttributes::Default(); 1184514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> key3(factory->NewFromASCII("3")); 1194514f5e3Sopenharmony_ci 1204514f5e3Sopenharmony_ci JSHandle<JSObject> objectHandle = factory->NewEmptyJSObject(); 1214514f5e3Sopenharmony_ci JSHandle<TaggedArray> keyArray = factory->NewTaggedArray(infoLength); 1224514f5e3Sopenharmony_ci JSHandle<LayoutInfo> layoutInfoHandle = factory->CreateLayoutInfo(infoLength); 1234514f5e3Sopenharmony_ci EXPECT_TRUE(*layoutInfoHandle != nullptr); 1244514f5e3Sopenharmony_ci std::vector<JSTaggedValue> keyVector; 1254514f5e3Sopenharmony_ci // Add key to layout info 1264514f5e3Sopenharmony_ci for (int i = 0; i < infoLength; i++) { 1274514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> elements(thread, JSTaggedValue(i)); 1284514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> elementsKey(JSTaggedValue::ToString(thread, elements)); 1294514f5e3Sopenharmony_ci defaultAttr.SetOffset(i); 1304514f5e3Sopenharmony_ci if (enumKeys) { 1314514f5e3Sopenharmony_ci if (i != 3) { // 3: index 1324514f5e3Sopenharmony_ci defaultAttr.SetEnumerable(false); 1334514f5e3Sopenharmony_ci } else { 1344514f5e3Sopenharmony_ci defaultAttr.SetEnumerable(true); 1354514f5e3Sopenharmony_ci } 1364514f5e3Sopenharmony_ci } 1374514f5e3Sopenharmony_ci layoutInfoHandle->AddKey(thread, i, elementsKey.GetTaggedValue(), defaultAttr); 1384514f5e3Sopenharmony_ci } 1394514f5e3Sopenharmony_ci if (enumKeys) { 1404514f5e3Sopenharmony_ci uint32_t keys = 0; 1414514f5e3Sopenharmony_ci layoutInfoHandle->GetAllEnumKeys(thread, infoLength, 0, keyArray, &keys, objectHandle); // 0: offset 1424514f5e3Sopenharmony_ci EXPECT_EQ(keyArray->Get(0), key3.GetTaggedValue()); 1434514f5e3Sopenharmony_ci EXPECT_EQ(keys, 1U); 1444514f5e3Sopenharmony_ci } else { 1454514f5e3Sopenharmony_ci layoutInfoHandle->GetAllKeys(thread, infoLength, 0, *keyArray, objectHandle); // 0: offset 1464514f5e3Sopenharmony_ci layoutInfoHandle->GetAllKeysForSerialization(infoLength, keyVector); 1474514f5e3Sopenharmony_ci EXPECT_EQ(keyArray->GetLength(), keyVector.size()); 1484514f5e3Sopenharmony_ci 1494514f5e3Sopenharmony_ci for (int i = 0;i < infoLength; i++) { 1504514f5e3Sopenharmony_ci bool result = JSTaggedValue::SameValue(keyArray->Get(i), keyVector[i]); 1514514f5e3Sopenharmony_ci EXPECT_TRUE(result); 1524514f5e3Sopenharmony_ci } 1534514f5e3Sopenharmony_ci } 1544514f5e3Sopenharmony_ci} 1554514f5e3Sopenharmony_ci 1564514f5e3Sopenharmony_ciHWTEST_F_L0(LayoutInfoTest, GetAllKeys) 1574514f5e3Sopenharmony_ci{ 1584514f5e3Sopenharmony_ci GetAllKeysCommon(thread); 1594514f5e3Sopenharmony_ci} 1604514f5e3Sopenharmony_ci 1614514f5e3Sopenharmony_ciHWTEST_F_L0(LayoutInfoTest, GetAllEnumKeys) 1624514f5e3Sopenharmony_ci{ 1634514f5e3Sopenharmony_ci GetAllKeysCommon(thread, true); 1644514f5e3Sopenharmony_ci} 1654514f5e3Sopenharmony_ci} // namespace panda::ecmascript 166