• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/layout_info.h"
17 #include "ecmascript/property_attributes.h"
18 #include "ecmascript/tests/test_helper.h"
19 
20 using namespace panda::ecmascript;
21 
22 namespace panda::test {
23 class LayoutInfoTest : public testing::Test {
24 public:
SetUpTestCase()25     static void SetUpTestCase()
26     {
27         GTEST_LOG_(INFO) << "SetUpTestCase";
28     }
29 
TearDownTestCase()30     static void TearDownTestCase()
31     {
32         GTEST_LOG_(INFO) << "TearDownCase";
33     }
34 
SetUp()35     void SetUp() override
36     {
37         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
38     }
39 
TearDown()40     void TearDown() override
41     {
42         TestHelper::DestroyEcmaVMWithScope(instance, scope);
43     }
44 
45     EcmaVM *instance {nullptr};
46     EcmaHandleScope *scope {nullptr};
47     JSThread *thread {nullptr};
48 };
49 
HWTEST_F_L0(LayoutInfoTest,SetNumberOfElements)50 HWTEST_F_L0(LayoutInfoTest, SetNumberOfElements)
51 {
52     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
53     int32_t infoLength = 2;
54     JSHandle<LayoutInfo> layoutInfoHandle = factory->CreateLayoutInfo(infoLength);
55     EXPECT_TRUE(*layoutInfoHandle != nullptr);
56 
57     layoutInfoHandle->SetNumberOfElements(thread, 100);
58     EXPECT_EQ(layoutInfoHandle->NumberOfElements(), 100);
59 }
60 
HWTEST_F_L0(LayoutInfoTest,SetPropertyInit)61 HWTEST_F_L0(LayoutInfoTest, SetPropertyInit)
62 {
63     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
64     int32_t infoLength = 3;
65     PropertyAttributes defaultAttr = PropertyAttributes::Default();
66     defaultAttr.SetNormalAttr(infoLength);
67     JSHandle<JSTaggedValue> key(factory->NewFromASCII("key"));
68     JSHandle<LayoutInfo> layoutInfoHandle = factory->CreateLayoutInfo(infoLength);
69     EXPECT_TRUE(*layoutInfoHandle != nullptr);
70 
71     layoutInfoHandle->SetPropertyInit(thread, 0, key.GetTaggedValue(), defaultAttr);
72     EXPECT_EQ(layoutInfoHandle->GetKey(0), key.GetTaggedValue());
73     EXPECT_EQ(layoutInfoHandle->GetAttr(0).GetNormalAttr(), static_cast<uint32_t>(infoLength));
74 }
75 
HWTEST_F_L0(LayoutInfoTest,SetSortedIndex)76 HWTEST_F_L0(LayoutInfoTest, SetSortedIndex)
77 {
78     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
79     int32_t infoLength = 5;
80     PropertyAttributes defaultAttr = PropertyAttributes::Default();
81     defaultAttr.SetNormalAttr(infoLength);
82     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("hello"));
83     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("world"));
84     JSHandle<LayoutInfo> layoutInfoHandle = factory->CreateLayoutInfo(infoLength);
85     EXPECT_TRUE(*layoutInfoHandle != nullptr);
86 
87     layoutInfoHandle->SetPropertyInit(thread, 0, key1.GetTaggedValue(), defaultAttr);
88     layoutInfoHandle->SetPropertyInit(thread, 1, key2.GetTaggedValue(), defaultAttr);
89     layoutInfoHandle->SetSortedIndex(thread, 0, infoLength - 4);
90     EXPECT_EQ(layoutInfoHandle->GetSortedIndex(0), 1U);
91     EXPECT_EQ(layoutInfoHandle->GetSortedKey(0), key2.GetTaggedValue());
92 }
93 
HWTEST_F_L0(LayoutInfoTest,FindElementWithCache)94 HWTEST_F_L0(LayoutInfoTest, FindElementWithCache)
95 {
96     int infoLength = 5;
97     int newPropertiesLength = 11;
98     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
99     PropertyAttributes defaultAttr = PropertyAttributes::Default();
100     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("1"));
101     JSHandle<JSTaggedValue> key4(factory->NewFromASCII("4"));
102     JSHandle<JSTaggedValue> key5(factory->NewFromASCII("5"));
103     JSHandle<JSTaggedValue> key10(factory->NewFromASCII("10"));
104     JSHandle<JSTaggedValue> key11(factory->NewFromASCII("11"));
105     JSHandle<LayoutInfo> layoutInfoHandle = factory->CreateLayoutInfo(infoLength);
106     EXPECT_TRUE(*layoutInfoHandle != nullptr);
107     for (int i = 0; i < infoLength; i++) {
108         JSHandle<JSTaggedValue> elements(thread, JSTaggedValue(i));
109         JSHandle<JSTaggedValue> elementsKey(JSTaggedValue::ToString(thread, elements));
110         defaultAttr.SetOffset(i);
111         layoutInfoHandle->AddKey(thread, i, elementsKey.GetTaggedValue(), defaultAttr);
112     }
113     int propertiesNumber = layoutInfoHandle->NumberOfElements();
114     int result = 0;
115     result = layoutInfoHandle->FindElementWithCache(thread, nullptr, key1.GetTaggedValue(), propertiesNumber);
116     EXPECT_EQ(result, 1); // 1: Index corresponding to key1
117     result = layoutInfoHandle->FindElementWithCache(thread, nullptr, key5.GetTaggedValue(), propertiesNumber);
118     EXPECT_EQ(result, -1); // -1: not find
119     // extend layoutInfo
120     JSHandle<LayoutInfo> newLayoutInfo = factory->ExtendLayoutInfo(layoutInfoHandle, newPropertiesLength);
121     for (int i = 5; i < newPropertiesLength; i++) {
122         JSHandle<JSTaggedValue> elements(thread, JSTaggedValue(i));
123         JSHandle<JSTaggedValue> elementsKey(JSTaggedValue::ToString(thread, elements));
124         defaultAttr.SetOffset(i);
125         newLayoutInfo->AddKey(thread, i, elementsKey.GetTaggedValue(), defaultAttr);
126     }
127     result = newLayoutInfo->FindElementWithCache(thread, nullptr, key4.GetTaggedValue(), newPropertiesLength);
128     EXPECT_EQ(result, 4); // 4: Index corresponding to key4
129     result = newLayoutInfo->FindElementWithCache(thread, nullptr, key10.GetTaggedValue(), newPropertiesLength);
130     EXPECT_EQ(result, 10); // 10: Index corresponding to key10
131     result = newLayoutInfo->FindElementWithCache(thread, nullptr, key5.GetTaggedValue(), newPropertiesLength);
132     EXPECT_EQ(result, 5); // 5: Index corresponding to key5
133     result = newLayoutInfo->FindElementWithCache(thread, nullptr, key11.GetTaggedValue(), newPropertiesLength);
134     EXPECT_EQ(result, -1); // -1: not find
135 }
136 
HWTEST_F_L0(LayoutInfoTest,GetAllKeys)137 HWTEST_F_L0(LayoutInfoTest, GetAllKeys)
138 {
139     int infoLength = 5;
140     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
141     PropertyAttributes defaultAttr = PropertyAttributes::Default();
142     JSHandle<JSTaggedValue> key3(factory->NewFromASCII("3"));
143 
144     JSHandle<JSObject> objectHandle = factory->NewEmptyJSObject();
145     JSHandle<TaggedArray> keyArray = factory->NewTaggedArray(infoLength);
146     JSHandle<LayoutInfo> layoutInfoHandle = factory->CreateLayoutInfo(infoLength);
147     EXPECT_TRUE(*layoutInfoHandle != nullptr);
148     std::vector<JSTaggedValue> keyVector;
149     // Add key to layout info
150     for (int i = 0; i < infoLength; i++) {
151         JSHandle<JSTaggedValue> elements(thread, JSTaggedValue(i));
152         JSHandle<JSTaggedValue> elementsKey(JSTaggedValue::ToString(thread, elements));
153         defaultAttr.SetOffset(i);
154         layoutInfoHandle->AddKey(thread, i, elementsKey.GetTaggedValue(), defaultAttr);
155     }
156     layoutInfoHandle->GetAllKeys(thread, infoLength, 0, *keyArray, objectHandle); // 0: offset
157     layoutInfoHandle->GetAllKeys(infoLength, keyVector, objectHandle);
158     EXPECT_EQ(keyArray->GetLength(), keyVector.size());
159 
160     for (int i = 0;i < infoLength; i++) {
161         bool result = JSTaggedValue::SameValue(keyArray->Get(i), keyVector[i]);
162         EXPECT_TRUE(result);
163     }
164 }
165 
HWTEST_F_L0(LayoutInfoTest,GetAllEnumKeys)166 HWTEST_F_L0(LayoutInfoTest, GetAllEnumKeys)
167 {
168     int infoLength = 5;
169     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
170     PropertyAttributes defaultAttr = PropertyAttributes::Default();
171     JSHandle<JSTaggedValue> key3(factory->NewFromASCII("3"));
172 
173     JSHandle<JSObject> objectHandle = factory->NewEmptyJSObject();
174     JSHandle<TaggedArray> keyArray = factory->NewTaggedArray(infoLength);
175     JSHandle<LayoutInfo> layoutInfoHandle = factory->CreateLayoutInfo(infoLength);
176     EXPECT_TRUE(*layoutInfoHandle != nullptr);
177     std::vector<JSTaggedValue> keyVector;
178     // Add key to layout info
179     for (int i = 0; i < infoLength; i++) {
180         JSHandle<JSTaggedValue> elements(thread, JSTaggedValue(i));
181         JSHandle<JSTaggedValue> elementsKey(JSTaggedValue::ToString(thread, elements));
182         defaultAttr.SetOffset(i);
183         if (i != 3) {
184             defaultAttr.SetEnumerable(false);
185         }
186         else {
187             defaultAttr.SetEnumerable(true);
188         }
189         layoutInfoHandle->AddKey(thread, i, elementsKey.GetTaggedValue(), defaultAttr);
190     }
191     uint32_t keys = 0;
192     layoutInfoHandle->GetAllEnumKeys(thread, infoLength, 0, *keyArray, &keys, objectHandle); // 0: offset
193     EXPECT_EQ(keyArray->Get(0), key3.GetTaggedValue());
194     EXPECT_EQ(keys, 1U);
195 }
196 }  // namespace panda::ecmascript