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
33using namespace panda::ecmascript;
34using namespace panda::ecmascript::builtins;
35
36namespace panda::test {
37using BuiltinsSharedSet = ecmascript::builtins::BuiltinsSharedSet;
38using JSSharedSet = ecmascript::JSSharedSet;
39
40class BuiltinsSharedSetTest : public BaseTestWithScope<false> {
41public:
42    class TestClass : public base::BuiltinsBase {
43    public:
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
58JSSharedSet *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
76JSSet *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
87enum class AlgorithmType {
88    ADD,
89    HAS,
90};
91
92JSTaggedValue 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
118HWTEST_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
127HWTEST_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
134HWTEST_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()
145HWTEST_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
184HWTEST_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
229HWTEST_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
265HWTEST_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
317HWTEST_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
365HWTEST_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
387HWTEST_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
407HWTEST_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