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/object_operator.h"
17#include "ecmascript/ecma_string.h"
18#include "ecmascript/global_env.h"
19#include "ecmascript/global_dictionary-inl.h"
20#include "ecmascript/js_array.h"
21#include "ecmascript/property_attributes.h"
22#include "ecmascript/tagged_array.h"
23#include "ecmascript/tagged_dictionary.h"
24#include "ecmascript/tests/test_helper.h"
25
26using namespace panda::ecmascript;
27
28namespace panda::test {
29class ObjectOperatorTest : public BaseTestWithScope<false> {
30};
31
32static JSFunction *JSObjectTestCreate(JSThread *thread)
33{
34    JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
35    return globalEnv->GetObjectFunction().GetObject<JSFunction>();
36}
37
38JSTaggedValue TestDefinedSetter([[maybe_unused]] EcmaRuntimeCallInfo *argv)
39{
40    // 12 : test case
41    return JSTaggedValue(12);
42}
43
44HWTEST_F_L0(ObjectOperatorTest, WriteDataProperty_001)
45{
46    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
47    JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
48    JSHandle<JSTaggedValue> handleKey(thread, JSTaggedValue(2));
49    JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(4));
50    uint32_t index = 1;
51    PropertyDescriptor handleDesc(thread);
52    ObjectOperator objectOperator(thread, handleKey);
53    PropertyAttributes handleAttr(4);
54    handleDesc.SetConfigurable(true); // Desc Set Configurable
55    objectOperator.SetAttr(PropertyAttributes(3));
56    objectOperator.SetIndex(index);
57    // object class is not DictionaryElement and object is Element
58    JSHandle<JSObject> handleObject = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
59    for (int i = 0; i < 3; i++) {
60        JSHandle<JSTaggedValue> newKey(thread, JSTaggedValue(i));
61        JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), newKey, newKey);
62    }
63    EXPECT_TRUE(objectOperator.WriteDataProperty(handleObject, handleDesc));
64    auto resultDict = NumberDictionary::Cast(handleObject->GetElements().GetTaggedObject());
65    int resultEntry = resultDict->FindEntry(JSTaggedValue(index));
66    int resultAttrValue = resultDict->GetAttributes(resultEntry).GetPropertyMetaData();
67
68    EXPECT_EQ(objectOperator.GetAttr().GetPropertyMetaData(), resultAttrValue);
69    EXPECT_EQ(objectOperator.GetAttr().GetDictionaryOrder(), 1U);
70    EXPECT_TRUE(objectOperator.GetAttr().IsConfigurable());
71    EXPECT_EQ(objectOperator.GetIndex(), static_cast<uint32_t>(resultEntry));
72    EXPECT_FALSE(objectOperator.IsFastMode());
73    EXPECT_TRUE(objectOperator.IsTransition());
74}
75
76HWTEST_F_L0(ObjectOperatorTest, WriteDataProperty_002)
77{
78    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
79    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
80    JSHandle<JSTaggedValue> handleKey(factory->NewFromASCII("key"));
81    JSHandle<JSTaggedValue> handleValue1(thread, JSTaggedValue(1));
82    JSHandle<JSTaggedValue> handleValue2(thread, JSTaggedValue(2));
83    JSHandle<PropertyBox> cellHandle1 = factory->NewPropertyBox(handleValue1);
84    JSHandle<PropertyBox> cellHandle2 = factory->NewPropertyBox(handleValue2);
85    PropertyDescriptor handleDesc(thread);
86    handleDesc.SetConfigurable(true);
87    PropertyAttributes handleAttr(2);
88    handleAttr.SetConfigurable(true);
89    // object is JSGlobalObject and not Element
90    JSHandle<JSTaggedValue> globalObj = env->GetJSGlobalObject();
91    JSHandle<JSObject> handleGlobalObject(globalObj);
92    ObjectOperator objectOperator(thread, handleGlobalObject, handleKey);
93
94    JSMutableHandle<GlobalDictionary> globalDict(thread, handleGlobalObject->GetProperties());
95    JSHandle<GlobalDictionary> handleDict = GlobalDictionary::Create(thread, 4);
96    globalDict.Update(handleDict.GetTaggedValue());
97    JSHandle<GlobalDictionary> handleProperties = GlobalDictionary::PutIfAbsent(
98        thread, globalDict, handleKey, JSHandle<JSTaggedValue>(cellHandle1), PropertyAttributes(4));
99    handleProperties->SetAttributes(thread, handleAttr.GetDictionaryOrder(), handleAttr);
100    handleProperties->SetValue(thread, handleAttr.GetDictionaryOrder(), cellHandle2.GetTaggedValue());
101    handleGlobalObject->SetProperties(thread, handleProperties.GetTaggedValue());
102    int resultEntry = handleProperties->FindEntry(handleKey.GetTaggedValue());
103    objectOperator.SetIndex(resultEntry);
104
105    EXPECT_TRUE(objectOperator.WriteDataProperty(handleGlobalObject, handleDesc));
106    auto resultDict = GlobalDictionary::Cast(handleGlobalObject->GetProperties().GetTaggedObject());
107    EXPECT_EQ(resultDict->GetAttributes(objectOperator.GetIndex()).GetPropertyMetaData(), 4);
108    EXPECT_TRUE(resultDict->GetAttributes(objectOperator.GetIndex()).IsConfigurable());
109
110    EXPECT_EQ(resultDict->GetAttributes(resultEntry).GetBoxType(), PropertyBoxType::MUTABLE);
111    EXPECT_EQ(resultDict->GetValue(resultEntry).GetInt(), 1);
112}
113
114HWTEST_F_L0(ObjectOperatorTest, WriteDataProperty_003)
115{
116    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
117    JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
118    JSHandle<JSTaggedValue> handleKey(factory->NewFromASCII("key"));
119    JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(2));
120    PropertyDescriptor handleDesc(thread, handleValue);
121    handleDesc.SetSetter(handleValue); // Desc is AccessorDescriptor
122    handleDesc.SetGetter(handleValue);
123    // object is not DictionaryMode and not Element
124    JSHandle<JSObject> handleObject = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
125    for (int i = 0; i < 3; i++) {
126        JSHandle<JSTaggedValue> newKey(thread, JSTaggedValue(i));
127        JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), newKey, newKey);
128    }
129    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), handleKey, handleValue);
130    ObjectOperator objectOperator1(thread, handleKey);
131    objectOperator1.SetAttr(PropertyAttributes(1));
132
133    EXPECT_TRUE(objectOperator1.WriteDataProperty(handleObject, handleDesc));
134    auto resultDict = NameDictionary::Cast(handleObject->GetProperties().GetTaggedObject());
135    int resultEntry = resultDict->FindEntry(handleKey.GetTaggedValue());
136    EXPECT_TRUE(resultDict->GetValue(resultEntry).IsAccessorData());
137    EXPECT_EQ(resultDict->GetAttributes(resultEntry).GetValue(), objectOperator1.GetAttr().GetValue());
138    // object is DictionaryMode and not Element
139    JSObject::DeleteProperty(thread, (handleObject), handleKey);
140    JSHandle<JSTaggedValue> handleSetter(factory->NewJSNativePointer(reinterpret_cast<void *>(TestDefinedSetter)));
141    JSHandle<AccessorData> handleAccessorData = factory->NewAccessorData();
142    handleDesc.SetSetter(handleSetter);
143    ObjectOperator objectOperator2(thread, handleKey);
144    objectOperator2.SetAttr(PropertyAttributes(handleDesc));
145    objectOperator2.SetValue(handleAccessorData.GetTaggedValue());
146    EXPECT_TRUE(objectOperator2.WriteDataProperty(handleObject, handleDesc));
147    JSHandle<AccessorData> resultAccessorData(thread, objectOperator2.GetValue());
148    EXPECT_EQ(resultAccessorData->GetGetter().GetInt(), 2);
149    EXPECT_TRUE(resultAccessorData->GetSetter().IsJSNativePointer());
150}
151
152HWTEST_F_L0(ObjectOperatorTest, Property_Add_001)
153{
154    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
155    JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
156    JSHandle<JSTaggedValue> handleKey(thread, JSTaggedValue(2));
157    JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(3));
158    int32_t elementIndex = 2;
159    PropertyAttributes handleAttr(elementIndex);
160    // object is JSArray and Element
161    JSHandle<JSArray> handleArr = factory->NewJSArray();
162    handleArr->SetArrayLength(thread, (elementIndex - 1));
163    JSHandle<JSTaggedValue> handleArrObj(thread, handleArr.GetTaggedValue());
164    ObjectOperator objectOperator1(thread, handleArrObj, elementIndex);
165    EXPECT_TRUE(objectOperator1.AddProperty(JSHandle<JSObject>(handleArrObj), handleValue, handleAttr));
166    EXPECT_EQ(handleArr->GetArrayLength(), 3U); // (elementIndex - 1) + 2
167    // object is DictionaryElement and Element
168    JSHandle<JSObject> handleObject = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
169    for (int i = 0; i < 3; i++) {
170        JSHandle<JSTaggedValue> newKey(thread, JSTaggedValue(i));
171        JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), newKey, newKey);
172    }
173    JSObject::DeleteProperty(thread, (handleObject), handleKey); // Delete key2
174    ObjectOperator objectOperator2(thread, JSHandle<JSTaggedValue>(handleObject), elementIndex);
175    EXPECT_TRUE(objectOperator2.AddProperty(handleObject, handleValue, handleAttr));
176    auto resultDict = NumberDictionary::Cast(handleObject->GetElements().GetTaggedObject());
177    int resultEntry = resultDict->FindEntry(JSTaggedValue(static_cast<uint32_t>(elementIndex)));
178    EXPECT_EQ(resultDict->GetKey(resultEntry).GetInt(), elementIndex);
179    EXPECT_EQ(resultDict->GetValue(resultEntry).GetInt(), 3);
180}
181
182HWTEST_F_L0(ObjectOperatorTest, Property_Add_002)
183{
184    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
185    JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
186    JSHandle<JSTaggedValue> handleString(factory->NewFromASCII("key"));
187    JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(3));
188    int32_t elementIndex = 4;
189    PropertyAttributes handleDefaultAttr(elementIndex);
190    PropertyAttributes handleAttr(elementIndex);
191    handleDefaultAttr.SetDefaultAttributes();
192    // object is not DictionaryMode and DefaultAttr
193    JSHandle<JSObject> handleObject1 = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
194    for (int i = 0; i < 3; i++) {
195        JSHandle<JSTaggedValue> newKey(thread, JSTaggedValue(i));
196        JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject1), newKey, newKey);
197    }
198    ObjectOperator objectOperator(thread, JSHandle<JSTaggedValue>(handleObject1), elementIndex);
199    EXPECT_TRUE(objectOperator.AddProperty(handleObject1, handleValue, handleDefaultAttr));
200    TaggedArray *resultArray = TaggedArray::Cast(handleObject1->GetElements().GetTaggedObject());
201    EXPECT_EQ(resultArray->Get(elementIndex).GetInt(), 3);
202    EXPECT_EQ(resultArray->GetLength(), 7U);
203    // object is not DictionaryMode and not DefaultAttr
204    JSHandle<JSObject> handleObject2 = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
205    for (int i = 0; i < 4; i++) {
206        JSHandle<JSTaggedValue> newKey(thread, JSTaggedValue(i));
207        JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject2), newKey, newKey);
208    }
209    EXPECT_TRUE(objectOperator.AddProperty(handleObject2, handleString, handleAttr));
210    auto resultDict = NumberDictionary::Cast(handleObject2->GetElements().GetTaggedObject());
211    int resultEntry = resultDict->FindEntry(JSTaggedValue(static_cast<uint32_t>(elementIndex)));
212    EXPECT_EQ(resultDict->GetKey(resultEntry).GetInt(), elementIndex);
213    EXPECT_TRUE(resultDict->GetValue(resultEntry).IsString());
214}
215
216HWTEST_F_L0(ObjectOperatorTest, Property_Add_003)
217{
218    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
219    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
220    JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
221    JSHandle<JSTaggedValue> handleKey(factory->NewFromASCII("key"));
222    JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(4));
223    int32_t handleAttrOffset = 4;
224    PropertyAttributes handleAttr(handleAttrOffset);
225    handleAttr.SetOffset(handleAttrOffset);
226    // object is JSGlobalObject and not Element
227    JSHandle<JSTaggedValue> globalObj = env->GetJSGlobalObject();
228    JSHandle<JSObject> handleGlobalObject(globalObj); // no properties
229    ObjectOperator objectOperator(thread, handleGlobalObject, handleKey);
230    EXPECT_TRUE(objectOperator.AddProperty(handleGlobalObject, handleValue, handleAttr));
231    EXPECT_EQ(objectOperator.GetAttr().GetBoxType(), PropertyBoxType::CONSTANT);
232    EXPECT_EQ(objectOperator.FastGetValue()->GetInt(), 4);
233    EXPECT_EQ(objectOperator.GetIndex(), 0U);
234    EXPECT_TRUE(objectOperator.IsFastMode());
235    EXPECT_FALSE(objectOperator.IsTransition());
236}
237
238HWTEST_F_L0(ObjectOperatorTest, Property_Add_004)
239{
240    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
241    JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
242    JSHandle<JSTaggedValue> handleKey(factory->NewFromASCII("key"));
243    JSHandle<JSTaggedValue> handleKey1(thread, JSTaggedValue(1));
244    JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(4));
245    JSHandle<JSTaggedValue> handledUndefinedVal(thread, JSTaggedValue::Undefined());
246    int32_t handleAttrOffset = 4;
247    PropertyAttributes handleAttr(handleAttrOffset);
248    handleAttr.SetOffset(handleAttrOffset);
249    // object is not DictionaryMode and not Element
250    JSHandle<JSObject> handleObject = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
251    for (int i = 0; i < 4; i++) {
252        JSHandle<JSTaggedValue> newKey(thread, JSTaggedValue(i));
253        JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), newKey, newKey);
254    }
255    EXPECT_EQ(handleObject->GetJSHClass()->GetInlinedProperties(), 4U);
256    ObjectOperator objectOperator(thread, handleObject, handleKey);
257    EXPECT_TRUE(objectOperator.AddProperty(handleObject, handleValue, handleAttr));
258    EXPECT_EQ(objectOperator.GetAttr().GetPropertyMetaData(), 4);
259    EXPECT_EQ(objectOperator.GetValue().GetInt(), 4);
260    EXPECT_EQ(objectOperator.GetIndex(), 0U); // 0 = 4 - 4
261    EXPECT_TRUE(objectOperator.IsFastMode());
262    EXPECT_TRUE(objectOperator.IsTransition());
263    // object is DictionaryMode and not Element
264    JSObject::DeleteProperty(thread, (handleObject), handleKey);
265    EXPECT_TRUE(objectOperator.AddProperty(handleObject, handledUndefinedVal, handleAttr));
266    EXPECT_EQ(objectOperator.GetAttr().GetPropertyMetaData(), 4);
267    EXPECT_TRUE(objectOperator.GetValue().IsUndefined());
268    EXPECT_EQ(objectOperator.GetIndex(), 0U);
269    EXPECT_FALSE(objectOperator.IsFastMode());
270    EXPECT_FALSE(objectOperator.IsTransition());
271}
272
273HWTEST_F_L0(ObjectOperatorTest, Property_DeleteElement1)
274{
275    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
276    JSHandle<JSTaggedValue> handleKey0(thread, JSTaggedValue(0));
277    JSHandle<JSTaggedValue> handleKey1(thread, JSTaggedValue(1));
278    JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(2));
279    uint32_t index = 1; // key value
280    PropertyAttributes handleAttr(index);
281
282    // object is not DictionaryMode
283    JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
284    JSHandle<JSObject> handleObject1 =
285        factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
286    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject1), handleKey0, handleKey0);
287    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject1), handleKey1, handleKey1);
288    TaggedArray *handleElements = TaggedArray::Cast(handleObject1->GetElements().GetTaggedObject());
289    EXPECT_EQ(handleElements->Get(index).GetInt(), 1);
290
291    ObjectOperator objectOperator1(thread, JSHandle<JSTaggedValue>(handleObject1), index);
292    objectOperator1.DeletePropertyInHolder();
293    TaggedArray *resultElements = TaggedArray::Cast(handleObject1->GetElements().GetTaggedObject());
294    EXPECT_EQ(resultElements->Get(index).GetInt(), 0);
295    auto resultDict1 = NumberDictionary::Cast(handleObject1->GetElements().GetTaggedObject());
296    EXPECT_TRUE(resultDict1->IsDictionaryMode());
297    EXPECT_TRUE(JSObject::GetProperty(thread, handleObject1, handleKey1).GetValue()->IsUndefined());
298    // object is DictionaryMode
299    JSHandle<JSObject> handleObject2 =
300        factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
301    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject2), handleKey0, handleKey0);
302    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject2), handleKey1, handleKey1);
303    JSObject::DeleteProperty(thread, (handleObject2), handleKey1);
304    ObjectOperator objectOperator2(thread, JSHandle<JSTaggedValue>(handleObject2), index - 1);
305    objectOperator2.DeletePropertyInHolder();
306    auto resultDict2 = NumberDictionary::Cast(handleObject2->GetElements().GetTaggedObject());
307    EXPECT_TRUE(resultDict2->GetKey(index - 1U).IsUndefined());
308    EXPECT_TRUE(resultDict2->GetValue(index - 1U).IsUndefined());
309    EXPECT_TRUE(JSObject::GetProperty(thread, handleObject2, handleKey0).GetValue()->IsUndefined());
310    EXPECT_TRUE(JSObject::GetProperty(thread, handleObject2, handleKey1).GetValue()->IsUndefined());
311}
312
313HWTEST_F_L0(ObjectOperatorTest, Property_DeleteElement2)
314{
315    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
316    JSHandle<JSTaggedValue> globalObj = env->GetJSGlobalObject();
317    JSHandle<JSObject> handleGlobalObject(globalObj);
318    JSHandle<NumberDictionary> handleDict = NumberDictionary::Create(thread, 4);
319    handleGlobalObject->SetElements(thread, handleDict.GetTaggedValue());
320    handleGlobalObject->GetClass()->SetIsDictionaryElement(true);
321    for (int i = 0; i < 10; i++) {
322        JSHandle<JSTaggedValue> handleKey(thread, JSTaggedValue(i));
323        JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(i));
324        JSObject::SetProperty(thread, globalObj, handleKey, handleValue);
325        JSObject::DeleteProperty(thread, handleGlobalObject, handleKey);
326    }
327    auto resultDict = NumberDictionary::Cast(handleGlobalObject->GetElements().GetTaggedObject());
328    EXPECT_EQ(resultDict->Size(), 4);
329}
330
331HWTEST_F_L0(ObjectOperatorTest, Property_DeleteProperty)
332{
333    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
334    JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
335    JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
336    JSHandle<JSTaggedValue> handleKey(factory->NewFromASCII("key"));
337    JSHandle<JSTaggedValue> handleKey0(thread, JSTaggedValue(0));
338    JSHandle<JSTaggedValue> handleKey1(thread, JSTaggedValue(1));
339    JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(33));
340    // object is JSGlobalObject
341    JSHandle<JSTaggedValue> globalObj = env->GetJSGlobalObject();
342    JSHandle<JSObject> handleGlobalObject(globalObj);
343    JSMutableHandle<GlobalDictionary> globalDict(thread, handleGlobalObject->GetProperties());
344    JSHandle<GlobalDictionary> handleDict = GlobalDictionary::Create(thread, 4);
345    globalDict.Update(handleDict.GetTaggedValue());
346    JSHandle<PropertyBox> cellHandle = factory->NewPropertyBox(handleKey);
347    cellHandle->SetValue(thread, handleValue.GetTaggedValue());
348    JSHandle<GlobalDictionary> handleProperties = GlobalDictionary::PutIfAbsent(
349        thread, globalDict, handleKey, JSHandle<JSTaggedValue>(cellHandle), PropertyAttributes(12));
350    handleGlobalObject->SetProperties(thread, handleProperties.GetTaggedValue());
351    ObjectOperator objectOperator1(thread, handleGlobalObject, handleKey);
352
353    objectOperator1.DeletePropertyInHolder();
354    auto resultDict = GlobalDictionary::Cast(handleGlobalObject->GetProperties().GetTaggedObject());
355    // key not found
356    EXPECT_EQ(resultDict->FindEntry(handleKey.GetTaggedValue()), -1);
357    EXPECT_EQ(resultDict->GetAttributes(objectOperator1.GetIndex()).GetValue(), 0U);
358    // object is not DictionaryMode
359    JSHandle<JSObject> handleObject =
360        factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
361    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), handleKey, handleKey1);
362    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), handleKey0, handleKey0);
363    JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), handleKey1, handleKey1);
364    ObjectOperator objectOperator2(thread, handleObject, handleKey);
365    objectOperator2.DeletePropertyInHolder();
366    auto resultDict1 = NameDictionary::Cast(handleObject->GetProperties().GetTaggedObject());
367    // key not found
368    EXPECT_EQ(resultDict1->FindEntry(handleKey.GetTaggedValue()), -1);
369}
370
371HWTEST_F_L0(ObjectOperatorTest, Define_SetterAndGettetr)
372{
373    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
374    JSHandle<AccessorData> handleAccessorData = factory->NewAccessorData();
375    JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(0));
376    JSHandle<JSTaggedValue> handleValue1(thread, JSTaggedValue(2));
377    JSHandle<EcmaString> handleKey(factory->NewFromASCII("value"));
378    JSHandle<JSTaggedValue> handleKey1(factory->NewFromASCII("key"));
379    JSHandle<JSTaggedValue> handleKey2(factory->NewFromASCII("value1"));
380    // object is not DictionaryMode
381    JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
382    JSHandle<JSObject> handleObject =
383        factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
384    for (int i = 0; i < 10; i++) {
385        JSHandle<JSTaggedValue> newValue(thread, JSTaggedValue(i));
386        JSHandle<EcmaString> newString =
387            factory->ConcatFromString(handleKey, JSTaggedValue::ToString(thread, newValue));
388        JSHandle<JSTaggedValue> newKey(thread, newString.GetTaggedValue());
389        JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), newKey, newValue);
390    }
391    // object is not Element
392    ObjectOperator objectOperator(thread, handleObject, handleKey1);
393    objectOperator.SetIndex(1);
394    objectOperator.SetValue(handleAccessorData.GetTaggedValue());
395    PropertyDescriptor handleDesc(thread, handleValue);
396    handleDesc.SetSetter(handleValue);
397    handleDesc.SetGetter(handleValue);
398    objectOperator.SetAttr(PropertyAttributes(handleDesc));
399    objectOperator.DefineSetter(handleValue1);
400    objectOperator.DefineGetter(handleValue);
401
402    JSHandle<JSObject> resultObj1(objectOperator.GetReceiver());
403    TaggedArray *properties = TaggedArray::Cast(resultObj1->GetProperties().GetTaggedObject());
404    JSHandle<AccessorData> resultAccessorData1(thread, properties->Get(objectOperator.GetIndex()));
405    EXPECT_EQ(resultAccessorData1->GetGetter().GetInt(), 0);
406    EXPECT_EQ(resultAccessorData1->GetSetter().GetInt(), 2);
407    // object is DictionaryMode
408    JSObject::DeleteProperty(thread, handleObject, handleKey2);
409    objectOperator.DefineSetter(handleValue);
410    objectOperator.DefineGetter(handleValue1);
411    JSHandle<JSObject> resultObj2(objectOperator.GetReceiver());
412    auto resultDict = NameDictionary::Cast(resultObj2->GetProperties().GetTaggedObject());
413    JSHandle<AccessorData> resultAccessorData2(thread, resultDict->GetValue(objectOperator.GetIndex()));
414    EXPECT_EQ(resultAccessorData2->GetGetter().GetInt(), 2);
415    EXPECT_EQ(resultAccessorData2->GetSetter().GetInt(), 0);
416}
417} // namespace panda::test