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/containers/containers_private.h"
17#include "ecmascript/ecma_string.h"
18#include "ecmascript/ecma_vm.h"
19#include "ecmascript/global_env.h"
20#include "ecmascript/js_function.h"
21#include "ecmascript/js_handle.h"
22#include "ecmascript/js_iterator.h"
23#include "ecmascript/js_api/js_api_hashmap.h"
24#include "ecmascript/js_api/js_api_hashmap_iterator.h"
25#include "ecmascript/js_object-inl.h"
26#include "ecmascript/js_tagged_value.h"
27#include "ecmascript/object_factory.h"
28#include "ecmascript/tests/ecma_test_common.h"
29
30using namespace panda;
31using namespace panda::ecmascript;
32
33namespace panda::test {
34class JSAPIHashMapTest : public BaseTestWithScope<false> {
35protected:
36    JSAPIHashMap *CreateHashMap()
37    {
38        return EcmaContainerCommon::CreateHashMap(thread);
39    }
40
41    void Update(JSHandle<JSAPIHashMap>& hashMap, JSMutableHandle<JSTaggedValue>& key,
42        JSMutableHandle<JSTaggedValue>& value, std::pair<std::string, std::string> myKeyVal, uint32_t numbers)
43    {
44        ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
45        for (uint32_t i = 0; i < numbers; i++) {
46            std::string iKey = myKeyVal.first + std::to_string(i);
47            std::string iValue = myKeyVal.second + std::to_string(i);
48            key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
49            value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
50            JSAPIHashMap::Set(thread, hashMap, key, value);
51        }
52    }
53};
54
55HWTEST_F_L0(JSAPIHashMapTest, HashMapCreate)
56{
57    JSAPIHashMap *map = CreateHashMap();
58    EXPECT_TRUE(map != nullptr);
59}
60
61HWTEST_F_L0(JSAPIHashMapTest, HashMapSetAndGet)
62{
63    constexpr uint32_t NODE_NUMBERS = 8;
64    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
65    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
66    JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
67
68    // test JSAPIHashMap
69    JSHandle<JSAPIHashMap> hashMap(thread, CreateHashMap());
70
71    // test IsEmpty
72    EXPECT_EQ(hashMap->IsEmpty(), JSTaggedValue::True());
73
74    // test Set exception
75    key.Update(JSTaggedValue::Undefined());
76    JSAPIHashMap::Set(thread, hashMap, key, value);
77    EXPECT_EXCEPTION();
78
79    std::string myKey("mykey");
80    std::string myValue("myvalue");
81    auto pair = std::make_pair(myKey, myValue);
82    Update(hashMap, key, value, pair, NODE_NUMBERS);
83    EXPECT_EQ(hashMap->GetSize(), NODE_NUMBERS);
84
85    // test isEmpty
86    EXPECT_EQ(hashMap->IsEmpty(), JSTaggedValue::False());
87
88    for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
89        std::string iKey = myKey + std::to_string(i);
90        std::string iValue = myValue + std::to_string(i);
91        key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
92        value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
93
94        // test get
95        JSTaggedValue gValue = hashMap->Get(thread, key.GetTaggedValue());
96        EXPECT_EQ(gValue, value.GetTaggedValue());
97    }
98}
99
100HWTEST_F_L0(JSAPIHashMapTest, HashMapRemoveAndHas)
101{
102    constexpr uint32_t NODE_NUMBERS = 8;
103    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
104    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
105    JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
106
107    // test JSAPIHashMap
108    JSHandle<JSAPIHashMap> hashMap(thread, CreateHashMap());
109
110    // test Remove Hole
111    JSTaggedValue undefined = JSAPIHashMap::Remove(thread, hashMap, JSTaggedValue::Hole());
112    EXPECT_EQ(undefined, JSTaggedValue::Undefined());
113
114    // test Remove empty hashmap
115    JSTaggedValue undefined1 = JSAPIHashMap::Remove(thread, hashMap, JSTaggedValue(0));
116    EXPECT_EQ(undefined1, JSTaggedValue::Undefined());
117
118    std::string myKey("mykey");
119    std::string myValue("myvalue");
120    auto pair = std::make_pair(myKey, myValue);
121    Update(hashMap, key, value, pair, NODE_NUMBERS);
122    EXPECT_EQ(hashMap->GetSize(), NODE_NUMBERS);
123
124    // test Remove non-existent
125    JSTaggedValue undefined2 = JSAPIHashMap::Remove(thread, hashMap, JSTaggedValue(0));
126    EXPECT_EQ(undefined2, JSTaggedValue::Undefined());
127
128    for (uint32_t i = 0; i < NODE_NUMBERS / 2; i++) {
129        std::string iKey = myKey + std::to_string(i);
130        key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
131        [[maybe_unused]] JSTaggedValue rValue = JSAPIHashMap::Remove(thread, hashMap, key.GetTaggedValue());
132    }
133    EXPECT_EQ(hashMap->GetSize(), NODE_NUMBERS / 2);
134
135    for (uint32_t i = 0; i < NODE_NUMBERS / 2; i++) {
136        std::string iKey = myKey + std::to_string(i);
137        std::string iValue = myValue + std::to_string(i);
138        key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
139        value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
140
141        // test has
142        JSTaggedValue hasKey = hashMap->HasKey(thread, key.GetTaggedValue());
143        EXPECT_EQ(hasKey, JSTaggedValue::False());
144        JSTaggedValue hasValue = JSAPIHashMap::HasValue(thread, hashMap, value);
145        EXPECT_EQ(hasValue, JSTaggedValue::False());
146    }
147
148    for (uint32_t i = NODE_NUMBERS / 2; i < NODE_NUMBERS; i++) {
149        std::string iKey = myKey + std::to_string(i);
150        std::string iValue = myValue + std::to_string(i);
151        key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
152        value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
153
154        // test has
155        JSTaggedValue hasKey = hashMap->HasKey(thread, key.GetTaggedValue());
156        EXPECT_EQ(hasKey, JSTaggedValue::True());
157        JSTaggedValue hasValue = JSAPIHashMap::HasValue(thread, hashMap, value);
158        EXPECT_EQ(hasValue, JSTaggedValue::True());
159    }
160}
161
162HWTEST_F_L0(JSAPIHashMapTest, HashMapReplaceAndClear)
163{
164    constexpr uint32_t NODE_NUMBERS = 8;
165    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
166    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
167    JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
168    // test TaggedHashMap
169    JSHandle<JSAPIHashMap> hashMap(thread, CreateHashMap());
170    std::string myKey("mykey");
171    std::string myValue("myvalue");
172    auto pair = std::make_pair(myKey, myValue);
173    Update(hashMap, key, value, pair, NODE_NUMBERS);
174    EXPECT_EQ(hashMap->GetSize(), NODE_NUMBERS);
175    for (uint32_t i = 0; i < NODE_NUMBERS / 2; i++) {
176        std::string iKey = myKey + std::to_string(i);
177        std::string iValue = myValue + std::to_string(i + 1);
178        key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
179        value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
180        // test replace
181        bool success = hashMap->Replace(thread, key.GetTaggedValue(), value.GetTaggedValue());
182        EXPECT_EQ(success, true);
183    }
184    for (uint32_t i = 0; i < NODE_NUMBERS / 2; i++) {
185        std::string iKey = myKey + std::to_string(i);
186        std::string iValue = myValue + std::to_string(i + 1);
187        key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
188        value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
189        // test get
190        JSTaggedValue gValue = hashMap->Get(thread, key.GetTaggedValue());
191        EXPECT_EQ(gValue, value.GetTaggedValue());
192    }
193    for (uint32_t i = NODE_NUMBERS / 2; i < NODE_NUMBERS; i++) {
194        std::string iKey = myKey + std::to_string(i);
195        std::string iValue = myValue + std::to_string(i);
196        key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
197        value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
198        // test get
199        JSTaggedValue gValue = hashMap->Get(thread, key.GetTaggedValue());
200        EXPECT_EQ(gValue, value.GetTaggedValue());
201    }
202    for (uint32_t i = 0; i < NODE_NUMBERS / 2; i++) {
203        std::string iKey = myKey + std::to_string(i);
204        key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
205        [[maybe_unused]] JSTaggedValue rValue = JSAPIHashMap::Remove(thread, hashMap, key.GetTaggedValue());
206    }
207    hashMap->Clear(thread);
208    EXPECT_EQ(hashMap->GetSize(), (uint32_t)0);
209    for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
210        std::string iKey = myKey + std::to_string(i);
211        std::string iValue = myValue + std::to_string(i);
212        key.Update(factory->NewFromStdString(iKey).GetTaggedValue());
213        value.Update(factory->NewFromStdString(iValue).GetTaggedValue());
214        // test get
215        JSTaggedValue gValue = hashMap->Get(thread, key.GetTaggedValue());
216        EXPECT_EQ(gValue, JSTaggedValue::Undefined());
217        // test has
218        JSTaggedValue hasKey = hashMap->HasKey(thread, key.GetTaggedValue());
219        EXPECT_EQ(hasKey, JSTaggedValue::False());
220        JSTaggedValue hasValue = JSAPIHashMap::HasValue(thread, hashMap, value);
221        EXPECT_EQ(hasValue, JSTaggedValue::False());
222    }
223}
224
225HWTEST_F_L0(JSAPIHashMapTest, JSAPIHashMapIterator)
226{
227    constexpr uint32_t NODE_NUMBERS = 8;
228    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
229    JSHandle<JSAPIHashMap> hashMap(thread, CreateHashMap());
230    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
231    JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
232    for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
233        key.Update(JSTaggedValue(i));
234        value.Update(JSTaggedValue(i));
235        JSAPIHashMap::Set(thread, hashMap, key, value);
236    }
237    // test key or value
238    JSHandle<JSTaggedValue> keyIter(factory->NewJSAPIHashMapIterator(hashMap, IterationKind::KEY));
239    JSHandle<JSTaggedValue> valueIter(factory->NewJSAPIHashMapIterator(hashMap, IterationKind::VALUE));
240    JSMutableHandle<JSTaggedValue> keyIterResult(thread, JSTaggedValue::Undefined());
241    JSMutableHandle<JSTaggedValue> valueIterResult(thread, JSTaggedValue::Undefined());
242    for (uint32_t i = 0; i < NODE_NUMBERS / 2; i++) {
243        keyIterResult.Update(JSIterator::IteratorStep(thread, keyIter).GetTaggedValue());
244        valueIterResult.Update(JSIterator::IteratorStep(thread, valueIter).GetTaggedValue());
245        JSHandle<JSTaggedValue> tmpIterKey = JSIterator::IteratorValue(thread, keyIterResult);
246        JSTaggedValue iterKeyFlag = hashMap->HasKey(thread, tmpIterKey.GetTaggedValue());
247        EXPECT_EQ(JSTaggedValue::True(), iterKeyFlag);
248        JSHandle<JSTaggedValue> tmpIterValue = JSIterator::IteratorValue(thread, valueIterResult);
249        JSTaggedValue iterValueFlag = JSAPIHashMap::HasValue(thread, hashMap, tmpIterValue);
250        EXPECT_EQ(JSTaggedValue::True(), iterValueFlag);
251    }
252    // test key and value
253    JSHandle<JSTaggedValue> indexKey(thread, JSTaggedValue(0));
254    JSHandle<JSTaggedValue> elementKey(thread, JSTaggedValue(1));
255    JSHandle<JSTaggedValue> iter(factory->NewJSAPIHashMapIterator(hashMap, IterationKind::KEY_AND_VALUE));
256    JSMutableHandle<JSTaggedValue> iterResult(thread, JSTaggedValue::Undefined());
257    JSMutableHandle<JSTaggedValue> result(thread, JSTaggedValue::Undefined());
258    for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
259        iterResult.Update(JSIterator::IteratorStep(thread, iter).GetTaggedValue());
260        result.Update(JSIterator::IteratorValue(thread, iterResult).GetTaggedValue());
261        JSHandle<JSTaggedValue> tmpKey = JSObject::GetProperty(thread, result, indexKey).GetValue();
262        JSTaggedValue iterKeyFlag = hashMap->HasKey(thread, tmpKey.GetTaggedValue());
263        EXPECT_EQ(JSTaggedValue::True(), iterKeyFlag);
264        JSHandle<JSTaggedValue> tmpValue = JSObject::GetProperty(thread, result, elementKey).GetValue();
265        JSTaggedValue iterValueFlag = JSAPIHashMap::HasValue(thread, hashMap, tmpValue);
266        EXPECT_EQ(JSTaggedValue::True(), iterValueFlag);
267    }
268    // test delete
269    key.Update(JSTaggedValue(NODE_NUMBERS / 2));
270    JSTaggedValue rValue = JSAPIHashMap::Remove(thread, hashMap, key.GetTaggedValue());
271    EXPECT_EQ(rValue, JSTaggedValue(NODE_NUMBERS / 2));
272    for (uint32_t i = NODE_NUMBERS / 2 + 1; i < NODE_NUMBERS; i++) {
273        keyIterResult.Update(JSIterator::IteratorStep(thread, keyIter).GetTaggedValue());
274        valueIterResult.Update(JSIterator::IteratorStep(thread, valueIter).GetTaggedValue());
275        JSHandle<JSTaggedValue> tmpIterKey = JSIterator::IteratorValue(thread, keyIterResult);
276        JSTaggedValue iterKeyFlag = hashMap->HasKey(thread, tmpIterKey.GetTaggedValue());
277        EXPECT_EQ(JSTaggedValue::True(), iterKeyFlag);
278        JSHandle<JSTaggedValue> tmpIterValue = JSIterator::IteratorValue(thread, valueIterResult);
279        JSTaggedValue iterValueFlag = JSAPIHashMap::HasValue(thread, hashMap, tmpIterValue);
280        EXPECT_EQ(JSTaggedValue::True(), iterValueFlag);
281    }
282    // test set
283    key.Update(JSTaggedValue(NODE_NUMBERS));
284    JSAPIHashMap::Set(thread, hashMap, key, key);
285    keyIterResult.Update(JSIterator::IteratorStep(thread, keyIter).GetTaggedValue());
286    JSHandle<JSTaggedValue> tmpIterKey = JSIterator::IteratorValue(thread, keyIterResult);
287    JSTaggedValue iterKeyFlag = hashMap->HasKey(thread, tmpIterKey.GetTaggedValue());
288    EXPECT_EQ(JSTaggedValue::True(), iterKeyFlag);
289    EXPECT_EQ(hashMap->GetSize(), NODE_NUMBERS);
290    keyIterResult.Update(JSIterator::IteratorStep(thread, keyIter).GetTaggedValue());
291    EXPECT_EQ(JSTaggedValue::False(), keyIterResult.GetTaggedValue());
292}
293
294HWTEST_F_L0(JSAPIHashMapTest, JSAPIHashMapIteratorRBTreeTest)
295{
296    constexpr uint32_t NODE_NUMBERS = 11;
297    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
298    JSHandle<JSAPIHashMap> hashMap(thread, CreateHashMap());
299    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
300    JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
301    JSHandle<JSTaggedValue> valueStr = thread->GlobalConstants()->GetHandledValueString();
302    std::vector<int> hashCollisionVector = {1224, 1285, 1463, 4307, 5135, 5903, 6603, 6780, 8416, 9401, 9740};
303
304    for (size_t i = 0; i < hashCollisionVector.size(); i++) {
305        key.Update(JSTaggedValue(hashCollisionVector[i]));
306        value.Update(JSTaggedValue(hashCollisionVector[i]));
307        JSAPIHashMap::Set(thread, hashMap, key, value);
308    }
309
310    JSHandle<JSAPIHashMapIterator> hashmapIterator = factory->NewJSAPIHashMapIterator(hashMap, IterationKind::VALUE);
311    for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
312        auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
313        ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
314        ecmaRuntimeCallInfo->SetThis(hashmapIterator.GetTaggedValue());
315
316        [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
317        JSTaggedValue result = JSAPIHashMapIterator::Next(ecmaRuntimeCallInfo);
318        TestHelper::TearDownFrame(thread, prev);
319
320        JSHandle<JSObject> resultObj(thread, result);
321        if (i <= NODE_NUMBERS - 1U) {
322            EXPECT_TRUE(JSObject::GetProperty(thread, resultObj, valueStr).GetValue()->IsInt());
323        }
324    }
325}
326
327HWTEST_F_L0(JSAPIHashMapTest, JSAPIHashMapRBTreeHasValueReplaceGet)
328{
329    std::vector<int> hashCollisionVector = {1224, 1285, 1463, 4307, 5135, 5903, 6780, 8416, 9401, 9740, 6603};
330    uint32_t NODE_NUMBERS = static_cast<uint32_t>(hashCollisionVector.size());
331    JSHandle<JSAPIHashMap> hashMap(thread, CreateHashMap());
332    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
333    JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
334
335    for (uint32_t i = 0; i < NODE_NUMBERS - 1; i++) {
336        key.Update(JSTaggedValue(hashCollisionVector[i]));
337        value.Update(JSTaggedValue(hashCollisionVector[i]));
338        JSAPIHashMap::Set(thread, hashMap, key, value);
339    }
340
341    // test RBTree HasValue
342    for (uint32_t i = 0; i < NODE_NUMBERS - 1; i++) {
343        value.Update(JSTaggedValue(hashCollisionVector[i]));
344        JSTaggedValue hasValue = JSAPIHashMap::HasValue(thread, hashMap, value);
345        EXPECT_EQ(hasValue, JSTaggedValue::True());
346    }
347    value.Update(JSTaggedValue(hashCollisionVector[NODE_NUMBERS - 1]));
348    JSTaggedValue hasValue = JSAPIHashMap::HasValue(thread, hashMap, value);
349    EXPECT_EQ(hasValue, JSTaggedValue::False());
350
351    // test RBTree Replace and Get
352    for (uint32_t i = 0; i < NODE_NUMBERS - 1; i++) {
353        bool replaceResult = hashMap->Replace(
354            thread, JSTaggedValue(hashCollisionVector[i]), JSTaggedValue(hashCollisionVector[i] * 2));
355        EXPECT_EQ(replaceResult, true);
356    }
357    for (uint32_t i = 0; i < NODE_NUMBERS - 1; i++) {
358        JSTaggedValue replaceResult = hashMap->Get(
359            thread, JSTaggedValue(hashCollisionVector[i]));
360        EXPECT_EQ(replaceResult, JSTaggedValue(hashCollisionVector[i] * 2));
361    }
362}
363
364HWTEST_F_L0(JSAPIHashMapTest, JSAPIHashMapRBTreeSetAllRemove)
365{
366    std::vector<int> hashCollisionVector = {1224, 1285, 1463, 4307, 5135, 5903, 6780, 8416, 9401, 9740, 6603};
367    uint32_t NODE_NUMBERS = static_cast<uint32_t>(hashCollisionVector.size());
368    uint32_t REMOVE_NUMBERS = 4;
369    JSHandle<JSAPIHashMap> dstHashMap(thread, CreateHashMap());
370    JSHandle<JSAPIHashMap> srcHashMap(thread, CreateHashMap());
371    JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
372    JSMutableHandle<JSTaggedValue> dstValue(thread, JSTaggedValue::Undefined());
373    JSMutableHandle<JSTaggedValue> srcValue(thread, JSTaggedValue::Undefined());
374
375    for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
376        key.Update(JSTaggedValue(hashCollisionVector[i]));
377        dstValue.Update(JSTaggedValue(hashCollisionVector[i]));
378        srcValue.Update(JSTaggedValue(hashCollisionVector[i] * 2));
379        JSAPIHashMap::Set(thread, dstHashMap, key, dstValue);
380        JSAPIHashMap::Set(thread, srcHashMap, key, srcValue);
381    }
382
383    // test SetAll and Get
384    JSAPIHashMap::SetAll(thread, dstHashMap, srcHashMap);
385    for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
386        JSTaggedValue replaceResult = dstHashMap->Get(
387            thread, JSTaggedValue(hashCollisionVector[i]));
388        EXPECT_EQ(replaceResult, JSTaggedValue(hashCollisionVector[i] * 2));
389    }
390
391    // test Remove RBTree
392    for (uint32_t i = 0; i < REMOVE_NUMBERS; i++) {
393        key.Update(JSTaggedValue(hashCollisionVector[i]));
394        JSAPIHashMap::Remove(thread, dstHashMap, key.GetTaggedValue());
395    }
396    EXPECT_EQ(dstHashMap->GetSize(), NODE_NUMBERS - REMOVE_NUMBERS);
397
398    for (uint32_t i = 0; i < REMOVE_NUMBERS; i++) {
399        JSTaggedValue getResult = dstHashMap->Get(thread, JSTaggedValue(hashCollisionVector[i]));
400        EXPECT_EQ(getResult, JSTaggedValue::Undefined());
401    }
402
403    for (uint32_t i = REMOVE_NUMBERS; i < NODE_NUMBERS; i++) {
404        JSTaggedValue getResult = dstHashMap->Get(thread, JSTaggedValue(hashCollisionVector[i]));
405        EXPECT_EQ(getResult, JSTaggedValue(hashCollisionVector[i] * 2));
406    }
407}
408}  // namespace panda::test
409