1 /*
2  * Copyright (c) 2024 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 #include "ecmascript/builtins/builtins_shared_set.h"
16 #include "ecmascript/shared_objects/js_shared_set.h"
17 #include "ecmascript/shared_objects/js_shared_set_iterator.h"
18 #include "ecmascript/ecma_string.h"
19 #include "ecmascript/ecma_vm.h"
20 #include "ecmascript/global_env.h"
21 #include "ecmascript/js_array.h"
22 #include "ecmascript/linked_hash_table.h"
23 #include "ecmascript/js_set.h"
24 #include "ecmascript/js_set_iterator.h"
25 #include "ecmascript/js_handle.h"
26 #include "ecmascript/js_hclass.h"
27 #include "ecmascript/js_object-inl.h"
28 #include "ecmascript/js_tagged_value.h"
29 #include "ecmascript/js_thread.h"
30 #include "ecmascript/object_factory.h"
31 #include "ecmascript/tests/test_helper.h"
32 
33 using namespace panda::ecmascript;
34 using namespace panda::ecmascript::builtins;
35 
36 namespace panda::test {
37 using BuiltinsSharedSet = ecmascript::builtins::BuiltinsSharedSet;
38 using JSSharedSet = ecmascript::JSSharedSet;
39 
40 class BuiltinsSharedSetTest : public BaseTestWithScope<false> {
41 public:
42     class TestClass : public base::BuiltinsBase {
43     public:
TestFunc(EcmaRuntimeCallInfo *argv)44         static JSTaggedValue TestFunc(EcmaRuntimeCallInfo *argv)
45         {
46             JSTaggedValue key = GetCallArg(argv, 0).GetTaggedValue();
47             if (key.IsUndefined()) {
48                 return JSTaggedValue::Undefined();
49             }
50             JSArray *jsArray = JSArray::Cast(GetThis(argv)->GetTaggedObject());
51             uint32_t length = jsArray->GetArrayLength() + 1U;
52             jsArray->SetArrayLength(argv->GetThread(), length);
53             return JSTaggedValue::Undefined();
54         }
55     };
56 };
57 
CreateBuiltinsSharedSet(JSThread *thread)58 JSSharedSet *CreateBuiltinsSharedSet(JSThread *thread)
59 {
60     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
61     JSHandle<JSFunction> newTarget(env->GetSBuiltininSetFunction());
62     // 4 : test case
63     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 4);
64     ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
65     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
66 
67     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
68     JSTaggedValue result = BuiltinsSharedSet::Constructor(ecmaRuntimeCallInfo);
69     TestHelper::TearDownFrame(thread, prev);
70 
71     EXPECT_TRUE(result.IsECMAObject());
72     JSSharedSet *jsSSet = JSSharedSet::Cast(reinterpret_cast<TaggedObject *>(result.GetRawData()));
73     return jsSSet;
74 }
75 
CreateJSSet(JSThread *thread)76 JSSet *CreateJSSet(JSThread *thread)
77 {
78     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
79     JSHandle<JSTaggedValue> constructor = thread->GetEcmaVM()->GetGlobalEnv()->GetBuiltinsSetFunction();
80     JSHandle<JSSet> set =
81         JSHandle<JSSet>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
82     JSHandle<LinkedHashSet> hashSet = LinkedHashSet::Create(thread);
83     set->SetLinkedSet(thread, hashSet);
84     return JSSet::Cast(set.GetTaggedValue().GetTaggedObject());
85 }
86 
87 enum class AlgorithmType {
88     ADD,
89     HAS,
90 };
91 
SharedSetAlgorithm(JSThread *thread, JSTaggedValue jsSet, std::vector<JSTaggedValue>& args, uint32_t argLen = 8, AlgorithmType type = AlgorithmType::ADD)92 JSTaggedValue SharedSetAlgorithm(JSThread *thread, JSTaggedValue jsSet, std::vector<JSTaggedValue>& args,
93     uint32_t argLen = 8, AlgorithmType type = AlgorithmType::ADD)
94 {
95     auto ecmaRuntimeCallInfos = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), argLen);
96     ecmaRuntimeCallInfos->SetFunction(JSTaggedValue::Undefined());
97     ecmaRuntimeCallInfos->SetThis(jsSet);
98     for (size_t i = 0; i < args.size(); i++) {
99         ecmaRuntimeCallInfos->SetCallArg(i, args[i]);
100     }
101     auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfos);
102     JSTaggedValue result;
103     switch (type) {
104         case AlgorithmType::ADD:
105             result = BuiltinsSharedSet::Add(ecmaRuntimeCallInfos);
106             break;
107         case AlgorithmType::HAS:
108             result = BuiltinsSharedSet::Has(ecmaRuntimeCallInfos);
109             break;
110         default:
111             break;
112     }
113     TestHelper::TearDownFrame(thread, prev);
114     return result;
115 }
116 
117 
HWTEST_F_L0(BuiltinsSharedSetTest, CreateSetIteratorTest001)118 HWTEST_F_L0(BuiltinsSharedSetTest, CreateSetIteratorTest001)
119 {
120     JSHandle<JSSet> jsSet(thread, CreateJSSet(thread));
121     EXPECT_TRUE(*jsSet != nullptr);
122     JSHandle<JSTaggedValue> setIteratorValue1 =
123         JSSharedSetIterator::CreateSetIterator(thread, JSHandle<JSTaggedValue>(jsSet), IterationKind::KEY);
124     EXPECT_EQ(setIteratorValue1->IsJSSetIterator(), false);
125 }
126 
HWTEST_F_L0(BuiltinsSharedSetTest, NextInternalTest001)127 HWTEST_F_L0(BuiltinsSharedSetTest, NextInternalTest001)
128 {
129     JSTaggedValue setIteratorValue1 =
130         JSSharedSetIterator::NextInternal(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
131     EXPECT_EQ(setIteratorValue1.IsJSSharedSetIterator(), false);
132 }
133 
HWTEST_F_L0(BuiltinsSharedSetTest, DeleteTest001)134 HWTEST_F_L0(BuiltinsSharedSetTest, DeleteTest001)
135 {
136     JSHandle<JSSharedSet> set(thread, CreateBuiltinsSharedSet(thread));
137     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(0));
138     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(1));
139     JSSharedSet::Add(thread, set, value1);
140     JSSharedSet::Add(thread, set, value2);
141     JSSharedSet::Delete(thread, set, JSHandle<JSTaggedValue>(thread, JSTaggedValue(20)));
142 }
143 
144 // new Set("abrupt").toString()
HWTEST_F_L0(BuiltinsSharedSetTest, CreateAndGetSize)145 HWTEST_F_L0(BuiltinsSharedSetTest, CreateAndGetSize)
146 {
147     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
148     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
149     JSHandle<JSFunction> newTarget(env->GetSBuiltininSetFunction());
150     JSHandle<JSSharedSet> set(thread, CreateBuiltinsSharedSet(thread));
151 
152     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
153     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
154     ecmaRuntimeCallInfo->SetThis(set.GetTaggedValue());
155     ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue::Undefined());
156     {
157         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
158         JSTaggedValue result = BuiltinsSharedSet::GetSize(ecmaRuntimeCallInfo);
159         TestHelper::TearDownFrame(thread, prev);
160 
161         EXPECT_EQ(result.GetRawData(), JSTaggedValue(0).GetRawData());
162     }
163 
164     JSHandle<TaggedArray> array(factory->NewTaggedArray(5));
165     for (int i = 0; i < 5; i++) {
166         array->Set(thread, i, JSTaggedValue(i));
167     }
168 
169     JSHandle<JSArray> values = JSArray::CreateArrayFromList(thread, array);
170     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
171     ecmaRuntimeCallInfo1->SetFunction(newTarget.GetTaggedValue());
172     ecmaRuntimeCallInfo1->SetThis(set.GetTaggedValue());
173     ecmaRuntimeCallInfo1->SetCallArg(0, values.GetTaggedValue());
174     ecmaRuntimeCallInfo1->SetNewTarget(newTarget.GetTaggedValue());
175     {
176         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
177         JSTaggedValue result1 = BuiltinsSharedSet::Constructor(ecmaRuntimeCallInfo1);
178         TestHelper::TearDownFrame(thread, prev);
179         JSHandle<JSSharedSet> set1(thread, JSSharedSet::Cast(reinterpret_cast<TaggedObject *>(result1.GetRawData())));
180         EXPECT_EQ(JSSharedSet::GetSize(thread, set1), 5);
181     }
182 }
183 
HWTEST_F_L0(BuiltinsSharedSetTest, AddAndHas)184 HWTEST_F_L0(BuiltinsSharedSetTest, AddAndHas)
185 {
186     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
187     // create jsSet
188     JSHandle<JSSharedSet> set(thread, CreateBuiltinsSharedSet(thread));
189     JSHandle<JSTaggedValue> key(thread, factory->NewFromASCII("key").GetTaggedValue());
190 
191     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
192     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
193     ecmaRuntimeCallInfo->SetThis(set.GetTaggedValue());
194     ecmaRuntimeCallInfo->SetCallArg(0, key.GetTaggedValue());
195 
196     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
197     JSTaggedValue result1 = BuiltinsSharedSet::Has(ecmaRuntimeCallInfo);
198     TestHelper::TearDownFrame(thread, prev);
199 
200     EXPECT_EQ(result1.GetRawData(), JSTaggedValue::False().GetRawData());
201 
202     // test Add()
203     JSTaggedValue result2 = BuiltinsSharedSet::Add(ecmaRuntimeCallInfo);
204     EXPECT_TRUE(result2.IsECMAObject());
205     JSSharedSet *jsSSet = JSSharedSet::Cast(reinterpret_cast<TaggedObject *>(result2.GetRawData()));
206     JSHandle<JSSharedSet> set2(thread, jsSSet);
207     EXPECT_EQ(JSSharedSet::GetSize(thread, set2), 1);
208 
209     // test Has()
210     JSTaggedValue jsSetTag(jsSSet);
211     std::vector<JSTaggedValue> args{key.GetTaggedValue()};
212     auto result3 = SharedSetAlgorithm(thread, jsSetTag, args, 6, AlgorithmType::HAS);
213 
214     EXPECT_EQ(result3.GetRawData(), JSTaggedValue::True().GetRawData());
215 
216     // test -0.0
217     JSHandle<JSTaggedValue> negativeZero(thread, JSTaggedValue(-0.0));
218     JSHandle<JSTaggedValue> positiveZero(thread, JSTaggedValue(+0.0));
219 
220     args[0] = negativeZero.GetTaggedValue();
221     SharedSetAlgorithm(thread, jsSetTag, args, 6, AlgorithmType::ADD);
222 
223     args[0] = positiveZero.GetTaggedValue();
224     auto result4 = SharedSetAlgorithm(thread, jsSetTag, args, 6, AlgorithmType::HAS);
225 
226     EXPECT_EQ(result4.GetRawData(), JSTaggedValue::True().GetRawData());
227 }
228 
HWTEST_F_L0(BuiltinsSharedSetTest, ForEach)229 HWTEST_F_L0(BuiltinsSharedSetTest, ForEach)
230 {
231     // generate a set has 5 entry{key1,key2,key3,key4,key5}
232     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
233     JSHandle<JSSharedSet> set(thread, CreateBuiltinsSharedSet(thread));
234     char keyArray[] = "key0";
235     for (uint32_t i = 0U; i < 5U; i++) {
236         keyArray[3] = '1' + i;
237         JSHandle<JSTaggedValue> key(factory->NewFromASCII(keyArray));
238 
239         std::vector<JSTaggedValue> args{key.GetTaggedValue()};
240         auto result1 = SharedSetAlgorithm(thread, set.GetTaggedValue(), args, 6, AlgorithmType::ADD);
241 
242         EXPECT_TRUE(result1.IsECMAObject());
243         JSHandle<JSSharedSet> set1(thread, JSSharedSet::Cast(reinterpret_cast<TaggedObject *>(result1.GetRawData())));
244         EXPECT_EQ(JSSharedSet::GetSize(thread, set1), static_cast<int>(i) + 1);
245     }
246     // test foreach
247     JSHandle<JSArray> jsArray(JSArray::ArrayCreate(thread, JSTaggedNumber(0)));
248     JSHandle<JSFunction> func =
249         factory->NewJSFunction(thread->GetEcmaVM()->GetGlobalEnv(), reinterpret_cast<void *>(TestClass::TestFunc));
250 
251     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
252     ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
253     ecmaRuntimeCallInfo1->SetThis(set.GetTaggedValue());
254     ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue());
255     ecmaRuntimeCallInfo1->SetCallArg(1, jsArray.GetTaggedValue());
256 
257     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
258     JSTaggedValue result2 = BuiltinsSharedSet::ForEach(ecmaRuntimeCallInfo1);
259     TestHelper::TearDownFrame(thread, prev);
260 
261     EXPECT_EQ(result2.GetRawData(), JSTaggedValue::VALUE_UNDEFINED);
262     EXPECT_EQ(jsArray->GetArrayLength(), 5U);
263 }
264 
HWTEST_F_L0(BuiltinsSharedSetTest, DeleteAndRemove)265 HWTEST_F_L0(BuiltinsSharedSetTest, DeleteAndRemove)
266 {
267     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
268     // create jsSet
269     JSHandle<JSSharedSet> set(thread, CreateBuiltinsSharedSet(thread));
270 
271     // add 40 keys
272     char keyArray[] = "key0";
273     for (uint32_t i = 0; i < 40; i++) {
274         keyArray[3] = '1' + i;
275         JSHandle<JSTaggedValue> key(factory->NewFromASCII(keyArray));
276         std::vector<JSTaggedValue> args{key.GetTaggedValue()};
277         auto result1 = SharedSetAlgorithm(thread, set.GetTaggedValue(), args, 6, AlgorithmType::ADD);
278 
279         EXPECT_TRUE(result1.IsECMAObject());
280         JSHandle<JSSharedSet> set1(thread, JSSharedSet::Cast(reinterpret_cast<TaggedObject *>(result1.GetRawData())));
281         EXPECT_EQ(JSSharedSet::GetSize(thread, set1), static_cast<int>(i) + 1);
282     }
283     // whether jsSet has delete key
284     keyArray[3] = '1' + 8;
285     JSHandle<JSTaggedValue> deleteKey(factory->NewFromASCII(keyArray));
286 
287     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
288     ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
289     ecmaRuntimeCallInfo1->SetThis(set.GetTaggedValue());
290     ecmaRuntimeCallInfo1->SetCallArg(0, deleteKey.GetTaggedValue());
291 
292     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
293     JSTaggedValue result2 = BuiltinsSharedSet::Has(ecmaRuntimeCallInfo1);
294 
295     EXPECT_EQ(result2.GetRawData(), JSTaggedValue::True().GetRawData());
296 
297     // delete
298     JSTaggedValue result3 = BuiltinsSharedSet::Delete(ecmaRuntimeCallInfo1);
299 
300     EXPECT_EQ(result3.GetRawData(), JSTaggedValue::True().GetRawData());
301 
302     // check deleteKey is deleted
303     JSTaggedValue result4 = BuiltinsSharedSet::Has(ecmaRuntimeCallInfo1);
304 
305     EXPECT_EQ(result4.GetRawData(), JSTaggedValue::False().GetRawData());
306 
307     JSTaggedValue result5 = BuiltinsSharedSet::GetSize(ecmaRuntimeCallInfo1);
308 
309     EXPECT_EQ(result5.GetRawData(), JSTaggedValue(39).GetRawData());
310 
311     // clear
312     JSTaggedValue result6 = BuiltinsSharedSet::Clear(ecmaRuntimeCallInfo1);
313     EXPECT_EQ(result6.GetRawData(), JSTaggedValue::VALUE_UNDEFINED);
314     EXPECT_EQ(set->JSSharedSet::GetSize(thread, set), 0);
315 }
316 
HWTEST_F_L0(BuiltinsSharedSetTest, Species)317 HWTEST_F_L0(BuiltinsSharedSetTest, Species)
318 {
319     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
320     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
321     JSHandle<JSTaggedValue> set(thread, CreateBuiltinsSharedSet(thread));
322     JSHandle<JSTaggedValue> speciesSymbol = env->GetSpeciesSymbol();
323     EXPECT_TRUE(!speciesSymbol->IsUndefined());
324 
325     JSHandle<JSFunction> newTarget(env->GetSBuiltininSetFunction());
326 
327     JSTaggedValue value =
328         JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(newTarget), speciesSymbol).GetValue().GetTaggedValue();
329     JSHandle<JSTaggedValue> valueHandle(thread, value);
330     EXPECT_EQ(value, newTarget.GetTaggedValue());
331 
332     // to string tag
333     JSHandle<JSTaggedValue> toStringTagSymbol = env->GetToStringTagSymbol();
334     JSHandle<EcmaString> stringTag(JSObject::GetProperty(thread, set, toStringTagSymbol).GetValue());
335     EXPECT_TRUE(!stringTag.GetTaggedValue().IsUndefined());
336 
337     JSHandle<JSFunction> constructor = JSHandle<JSFunction>::Cast(JSTaggedValue::ToObject(thread, valueHandle));
338     EXPECT_EQ(JSTaggedValue::GetPrototype(thread, set), constructor->GetFunctionPrototype());
339 
340     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("add"));
341     JSTaggedValue value1 = JSObject::GetProperty(thread, set, key1).GetValue().GetTaggedValue();
342     EXPECT_FALSE(value1.IsUndefined());
343 
344     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("has"));
345     JSTaggedValue value2 = JSObject::GetProperty(thread, set, key1).GetValue().GetTaggedValue();
346     EXPECT_FALSE(value2.IsUndefined());
347 
348     JSHandle<JSTaggedValue> key3(factory->NewFromASCII("clear"));
349     JSTaggedValue value3 = JSObject::GetProperty(thread, set, key1).GetValue().GetTaggedValue();
350     EXPECT_FALSE(value3.IsUndefined());
351 
352     JSHandle<JSTaggedValue> key4(factory->NewFromASCII("size"));
353     JSTaggedValue value4 = JSObject::GetProperty(thread, set, key1).GetValue().GetTaggedValue();
354     EXPECT_FALSE(value4.IsUndefined());
355 
356     JSHandle<JSTaggedValue> key5(factory->NewFromASCII("delete"));
357     JSTaggedValue value5 = JSObject::GetProperty(thread, set, key1).GetValue().GetTaggedValue();
358     EXPECT_FALSE(value5.IsUndefined());
359 
360     JSHandle<JSTaggedValue> key6(factory->NewFromASCII("forEach"));
361     JSTaggedValue value6 = JSObject::GetProperty(thread, set, key1).GetValue().GetTaggedValue();
362     EXPECT_FALSE(value6.IsUndefined());
363 }
364 
HWTEST_F_L0(BuiltinsSharedSetTest, GetIterator)365 HWTEST_F_L0(BuiltinsSharedSetTest, GetIterator)
366 {
367     JSHandle<JSTaggedValue> set(thread, CreateBuiltinsSharedSet(thread));
368 
369     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
370     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
371     ecmaRuntimeCallInfo->SetThis(set.GetTaggedValue());
372     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
373 
374     // test Values()
375     JSTaggedValue result = BuiltinsSharedSet::Values(ecmaRuntimeCallInfo);
376     JSHandle<JSSharedSetIterator> iter(thread, result);
377     EXPECT_TRUE(result.IsJSSharedSetIterator());
378     EXPECT_EQ(IterationKind::VALUE, IterationKind(iter->GetIterationKind()));
379 
380     // test entries()
381     JSTaggedValue result2 = BuiltinsSharedSet::Entries(ecmaRuntimeCallInfo);
382     JSHandle<JSSharedSetIterator> iter2(thread, result2);
383     EXPECT_TRUE(result2.IsJSSharedSetIterator());
384     EXPECT_EQ(IterationKind::KEY_AND_VALUE, iter2->GetIterationKind());
385 }
386 
HWTEST_F_L0(BuiltinsSharedSetTest, GetValue)387 HWTEST_F_L0(BuiltinsSharedSetTest, GetValue)
388 {
389     JSHandle<JSTaggedValue> set(thread, CreateBuiltinsSharedSet(thread));
390 
391     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
392     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
393     ecmaRuntimeCallInfo->SetThis(set.GetTaggedValue());
394     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
395 
396     JSTaggedValue result = BuiltinsSharedSet::Values(ecmaRuntimeCallInfo);
397     JSHandle<JSSharedSetIterator> iter(thread, result);
398     EXPECT_TRUE(result.IsJSSharedSetIterator());
399     EXPECT_EQ(IterationKind::VALUE, IterationKind(iter->GetIterationKind()));
400 
401     JSTaggedValue result2 = BuiltinsSharedSet::Entries(ecmaRuntimeCallInfo);
402     JSHandle<JSSharedSetIterator> iter2(thread, result2);
403     EXPECT_TRUE(result2.IsJSSharedSetIterator());
404     EXPECT_EQ(IterationKind::KEY_AND_VALUE, iter2->GetIterationKind());
405 }
406 
HWTEST_F_L0(BuiltinsSharedSetTest, KEY_AND_VALUE_Next)407 HWTEST_F_L0(BuiltinsSharedSetTest, KEY_AND_VALUE_Next)
408 {
409     JSHandle<JSTaggedValue> index0(thread, JSTaggedValue(0));
410     JSHandle<JSTaggedValue> index1(thread, JSTaggedValue(1));
411     JSHandle<JSSharedSetIterator> setIterator;
412     JSHandle<JSSharedSet> jsSet(thread, CreateBuiltinsSharedSet(thread));
413     EXPECT_TRUE(*jsSet != nullptr);
414 
415     for (int i = 0; i < 3; i++) {  // 3 : 3 default numberOfElements
416         JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i));
417         JSSharedSet::Add(thread, jsSet, key);
418     }
419     // set IterationKind(key or value)
420     JSHandle<JSTaggedValue> setIteratorValue =
421         JSSharedSetIterator::CreateSetIterator(thread, JSHandle<JSTaggedValue>(jsSet), IterationKind::KEY_AND_VALUE);
422     setIterator = JSHandle<JSSharedSetIterator>(setIteratorValue);
423     std::vector<JSTaggedValue> args{JSTaggedValue::Undefined()};
424     auto ecmaRuntimeCallInfo =
425         TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 6, setIteratorValue.GetTaggedValue());
426     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
427 
428     for (int i = 0; i <= 3; i++) { // 3 : 3 default numberOfElements
429         JSTaggedValue result = JSSharedSetIterator::Next(ecmaRuntimeCallInfo);
430         JSHandle<JSTaggedValue> resultObj(thread, result);
431         if (i < 3) {
432             JSHandle<JSArray> arrayList(thread, JSIterator::IteratorValue(thread, resultObj).GetTaggedValue());
433             EXPECT_EQ(setIterator->GetNextIndex(), static_cast<uint32_t>(i+1));
434             EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(arrayList), index0).GetValue()->GetInt(), i);
435             EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(arrayList), index1).GetValue()->GetInt(), i);
436         }
437         else {
438             EXPECT_EQ(JSIterator::IteratorValue(thread, resultObj).GetTaggedValue(), JSTaggedValue::Undefined());
439         }
440     }
441     TestHelper::TearDownFrame(thread, prev);
442 }
443 
444 }  // namespace panda::test
445