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/js_api/js_api_lightweightset.h"
17
18 #include "ecmascript/containers/containers_lightweightset.h"
19 #include "ecmascript/containers/containers_private.h"
20 #include "ecmascript/ecma_runtime_call_info.h"
21 #include "ecmascript/global_env.h"
22
23 #include "ecmascript/js_api/js_api_lightweightset_iterator.h"
24 #include "ecmascript/js_handle.h"
25 #include "ecmascript/js_tagged_value-inl.h"
26 #include "ecmascript/js_thread.h"
27 #include "ecmascript/object_factory.h"
28 #include "ecmascript/tests/test_helper.h"
29 #include "ecmascript/containers/tests/containers_test_helper.h"
30
31 using namespace panda::ecmascript;
32 using namespace panda::ecmascript::containers;
33
34 namespace panda::test {
35 class ContainersLightWeightSetTest : public testing::Test {
36 public:
SetUpTestCase()37 static void SetUpTestCase()
38 {
39 GTEST_LOG_(INFO) << "SetUpTestCase";
40 }
41
TearDownTestCase()42 static void TearDownTestCase()
43 {
44 GTEST_LOG_(INFO) << "TearDownCase";
45 }
46
SetUp()47 void SetUp() override
48 {
49 TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
50 }
51
TearDown()52 void TearDown() override
53 {
54 TestHelper::DestroyEcmaVMWithScope(instance, scope);
55 }
56
57 EcmaVM *instance {nullptr};
58 EcmaHandleScope *scope {nullptr};
59 JSThread *thread {nullptr};
60
61 class TestClass : public base::BuiltinsBase {
62 public:
TestForEachFunc(EcmaRuntimeCallInfo * argv)63 static JSTaggedValue TestForEachFunc(EcmaRuntimeCallInfo *argv)
64 {
65 JSThread *thread = argv->GetThread();
66 JSHandle<JSTaggedValue> value = GetCallArg(argv, 0); // 0 means the first argument vector
67 JSHandle<JSAPILightWeightSet> jSAPILightWeightSet(GetThis(argv));
68 JSAPILightWeightSet::Add(thread, jSAPILightWeightSet, value);
69 return JSTaggedValue::Undefined();
70 }
71 };
72 protected:
InitializeLightWeightSetConstructor()73 JSTaggedValue InitializeLightWeightSetConstructor()
74 {
75 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
76 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
77 JSHandle<JSTaggedValue> globalObject = env->GetJSGlobalObject();
78 JSHandle<JSTaggedValue> key(factory->NewFromASCII("ArkPrivate"));
79 JSHandle<JSTaggedValue> value =
80 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(globalObject), key).GetValue();
81 auto objCallInfo =
82 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value
83 objCallInfo->SetFunction(JSTaggedValue::Undefined());
84 objCallInfo->SetThis(value.GetTaggedValue());
85 objCallInfo->SetCallArg(
86 0, JSTaggedValue(static_cast<int>(ContainerTag::LightWeightSet))); // 0 means the argument
87 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
88 JSTaggedValue result = ContainersPrivate::Load(objCallInfo);
89 TestHelper::TearDownFrame(thread, prev);
90
91 return result;
92 }
93
CreateJSAPILightWeightSet()94 JSHandle<JSAPILightWeightSet> CreateJSAPILightWeightSet()
95 {
96 JSHandle<JSFunction> newTarget(thread, InitializeLightWeightSetConstructor());
97 auto objCallInfo =
98 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); // 4 means the value
99 objCallInfo->SetFunction(newTarget.GetTaggedValue());
100 objCallInfo->SetNewTarget(newTarget.GetTaggedValue());
101 objCallInfo->SetThis(JSTaggedValue::Undefined());
102
103 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
104 JSTaggedValue result = ContainersLightWeightSet::LightWeightSetConstructor(objCallInfo);
105 TestHelper::TearDownFrame(thread, prev);
106 JSHandle<JSAPILightWeightSet> map(thread, result);
107 return map;
108 }
109 };
110
HWTEST_F_L0(ContainersLightWeightSetTest,LightWeightSetConstructor)111 HWTEST_F_L0(ContainersLightWeightSetTest, LightWeightSetConstructor)
112 {
113 InitializeLightWeightSetConstructor();
114 JSHandle<JSFunction> newTarget(thread, InitializeLightWeightSetConstructor());
115 auto objCallInfo =
116 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); // 4 means the value
117 objCallInfo->SetFunction(newTarget.GetTaggedValue());
118 objCallInfo->SetNewTarget(newTarget.GetTaggedValue());
119 objCallInfo->SetThis(JSTaggedValue::Undefined());
120
121 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
122 JSTaggedValue result = ContainersLightWeightSet::LightWeightSetConstructor(objCallInfo);
123 TestHelper::TearDownFrame(thread, prev);
124
125 ASSERT_TRUE(result.IsJSAPILightWeightSet());
126 JSHandle<JSAPILightWeightSet> mapHandle(thread, result);
127 JSTaggedValue resultProto = JSObject::GetPrototype(JSHandle<JSObject>::Cast(mapHandle));
128 JSTaggedValue funcProto = newTarget->GetFunctionPrototype();
129 ASSERT_EQ(resultProto, funcProto);
130 int length = mapHandle->GetLength();
131 ASSERT_EQ(length, 0); // 0 means the value
132
133 // test LightWeightSetConstructor exception
134 objCallInfo->SetNewTarget(JSTaggedValue::Undefined());
135 CONTAINERS_API_EXCEPTION_TEST(ContainersLightWeightSet, LightWeightSetConstructor, objCallInfo);
136 }
137
HWTEST_F_L0(ContainersLightWeightSetTest,AddAndGetValueAt)138 HWTEST_F_L0(ContainersLightWeightSetTest, AddAndGetValueAt)
139 {
140 constexpr uint32_t NODE_NUMBERS = 8; // 8 means the value
141 JSHandle<JSAPILightWeightSet> lightWeightSet = CreateJSAPILightWeightSet();
142 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
143 auto callInfo =
144 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value
145 callInfo->SetFunction(JSTaggedValue::Undefined());
146 callInfo->SetThis(lightWeightSet.GetTaggedValue());
147 callInfo->SetCallArg(0, JSTaggedValue(i + 1));
148
149 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
150 JSTaggedValue result = ContainersLightWeightSet::Add(callInfo);
151 EXPECT_TRUE(JSTaggedValue::Equal(thread, JSHandle<JSTaggedValue>(thread, result),
152 JSHandle<JSTaggedValue>(thread, JSTaggedValue::True())));
153 TestHelper::TearDownFrame(thread, prev);
154 int length = lightWeightSet->GetLength();
155 EXPECT_EQ(length, static_cast<int>(i + 1));
156 }
157
158 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
159 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
160 std::string myValue("myvalue");
161 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
162 std::string ivalue = myValue + std::to_string(i);
163 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
164 auto callInfo =
165 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value
166 callInfo->SetFunction(JSTaggedValue::Undefined());
167 callInfo->SetThis(lightWeightSet.GetTaggedValue());
168 callInfo->SetCallArg(0, value.GetTaggedValue());
169 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
170 JSTaggedValue result = ContainersLightWeightSet::Add(callInfo);
171 TestHelper::TearDownFrame(thread, prev);
172 int length = lightWeightSet->GetLength();
173 EXPECT_TRUE(JSTaggedValue::Equal(thread, JSHandle<JSTaggedValue>(thread, result),
174 JSHandle<JSTaggedValue>(thread, JSTaggedValue::True())));
175 EXPECT_EQ(length, static_cast<int>(NODE_NUMBERS + 1 + i));
176 }
177 }
178
HWTEST_F_L0(ContainersLightWeightSetTest,AddAll)179 HWTEST_F_L0(ContainersLightWeightSetTest, AddAll)
180 {
181 constexpr uint32_t NODE_NUMBERS = 8; // 8 means the value
182 JSHandle<JSAPILightWeightSet> lightWeightSet = CreateJSAPILightWeightSet();
183 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
184 auto callInfo =
185 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value
186 callInfo->SetFunction(JSTaggedValue::Undefined());
187 callInfo->SetThis(lightWeightSet.GetTaggedValue());
188 callInfo->SetCallArg(0, JSTaggedValue(i + 1));
189
190 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
191 JSTaggedValue result = ContainersLightWeightSet::Add(callInfo);
192 EXPECT_TRUE(JSTaggedValue::Equal(thread, JSHandle<JSTaggedValue>(thread, result),
193 JSHandle<JSTaggedValue>(thread, JSTaggedValue::True())));
194 TestHelper::TearDownFrame(thread, prev);
195 int length = lightWeightSet->GetLength();
196 EXPECT_EQ(length, static_cast<int>(i + 1));
197 }
198
199 JSHandle<JSAPILightWeightSet> lws = CreateJSAPILightWeightSet();
200 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
201 auto callInfo =
202 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value
203 callInfo->SetFunction(JSTaggedValue::Undefined());
204 callInfo->SetThis(lws.GetTaggedValue());
205 callInfo->SetCallArg(0, JSTaggedValue(i + 1 + 10));
206
207 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
208 JSTaggedValue result = ContainersLightWeightSet::Add(callInfo);
209 EXPECT_TRUE(JSTaggedValue::Equal(thread, JSHandle<JSTaggedValue>(thread, result),
210 JSHandle<JSTaggedValue>(thread, JSTaggedValue::True())));
211 TestHelper::TearDownFrame(thread, prev);
212 int length = lws->GetLength();
213 EXPECT_EQ(length, static_cast<int>(i + 1));
214 }
215 // test AddAll
216 {
217 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
218 callInfo->SetFunction(JSTaggedValue::Undefined());
219 callInfo->SetThis(lightWeightSet.GetTaggedValue());
220 callInfo->SetCallArg(0, lws.GetTaggedValue());
221
222 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
223 JSTaggedValue result = ContainersLightWeightSet::AddAll(callInfo);
224 TestHelper::TearDownFrame(thread, prev);
225 int length = lightWeightSet->GetLength();
226 EXPECT_EQ(length, static_cast<int>(NODE_NUMBERS * 2));
227 EXPECT_TRUE(JSTaggedValue::Equal(thread, JSHandle<JSTaggedValue>(thread, result),
228 JSHandle<JSTaggedValue>(thread, JSTaggedValue::True())));
229 }
230 }
231
HWTEST_F_L0(ContainersLightWeightSetTest,HasAllAndHas)232 HWTEST_F_L0(ContainersLightWeightSetTest, HasAllAndHas)
233 {
234 constexpr uint32_t NODE_NUMBERS = 8; // 8 means the value
235 JSHandle<JSAPILightWeightSet> lightWeightSet = CreateJSAPILightWeightSet();
236 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
237 auto callInfo =
238 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value
239 callInfo->SetFunction(JSTaggedValue::Undefined());
240 callInfo->SetThis(lightWeightSet.GetTaggedValue());
241 callInfo->SetCallArg(0, JSTaggedValue(i + 1));
242
243 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
244 JSTaggedValue result = ContainersLightWeightSet::Add(callInfo);
245 EXPECT_TRUE(JSTaggedValue::Equal(thread, JSHandle<JSTaggedValue>(thread, result),
246 JSHandle<JSTaggedValue>(thread, JSTaggedValue::True())));
247 TestHelper::TearDownFrame(thread, prev);
248 int length = lightWeightSet->GetLength();
249 EXPECT_EQ(length, static_cast<int>(i + 1));
250 }
251
252 JSHandle<JSAPILightWeightSet> lws = CreateJSAPILightWeightSet();
253 for (uint32_t i = 3; i < NODE_NUMBERS - 2; i++) {
254 auto callInfo =
255 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value
256 callInfo->SetFunction(JSTaggedValue::Undefined());
257 callInfo->SetThis(lws.GetTaggedValue());
258 callInfo->SetCallArg(0, JSTaggedValue(i + 1));
259
260 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
261 JSTaggedValue result = ContainersLightWeightSet::Add(callInfo);
262 EXPECT_TRUE(JSTaggedValue::Equal(thread, JSHandle<JSTaggedValue>(thread, result),
263 JSHandle<JSTaggedValue>(thread, JSTaggedValue::True())));
264 TestHelper::TearDownFrame(thread, prev);
265 }
266 // test HasAll true
267 {
268 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
269 callInfo->SetFunction(JSTaggedValue::Undefined());
270 callInfo->SetThis(lightWeightSet.GetTaggedValue());
271 callInfo->SetCallArg(0, lws.GetTaggedValue());
272
273 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
274 JSTaggedValue result = ContainersLightWeightSet::HasAll(callInfo);
275 TestHelper::TearDownFrame(thread, prev);
276 EXPECT_TRUE(JSTaggedValue::Equal(thread, JSHandle<JSTaggedValue>(thread, result),
277 JSHandle<JSTaggedValue>(thread, JSTaggedValue::True())));
278 }
279 // test HasAll fales
280 JSHandle<JSAPILightWeightSet> lwsFalse = CreateJSAPILightWeightSet();
281 for (uint32_t i = 1; i < NODE_NUMBERS - 2; i++) {
282 auto callInfo =
283 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value
284 callInfo->SetFunction(JSTaggedValue::Undefined());
285 callInfo->SetThis(lwsFalse.GetTaggedValue());
286
287 if (i == 2) {
288 callInfo->SetCallArg(0, JSTaggedValue(i + 1 + 10));
289 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
290 JSTaggedValue result = ContainersLightWeightSet::Add(callInfo);
291 EXPECT_TRUE(JSTaggedValue::Equal(thread, JSHandle<JSTaggedValue>(thread, result),
292 JSHandle<JSTaggedValue>(thread, JSTaggedValue::True())));
293 } else {
294 callInfo->SetCallArg(0, JSTaggedValue(i + 1));
295 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
296 JSTaggedValue result = ContainersLightWeightSet::Add(callInfo);
297 EXPECT_TRUE(JSTaggedValue::Equal(thread, JSHandle<JSTaggedValue>(thread, result),
298 JSHandle<JSTaggedValue>(thread, JSTaggedValue::True())));
299 }
300 }
301 {
302 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
303 callInfo->SetFunction(JSTaggedValue::Undefined());
304 callInfo->SetThis(lightWeightSet.GetTaggedValue());
305 callInfo->SetCallArg(0, lwsFalse.GetTaggedValue());
306
307 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
308 JSTaggedValue result = ContainersLightWeightSet::HasAll(callInfo);
309 TestHelper::TearDownFrame(thread, prev);
310 EXPECT_TRUE(JSTaggedValue::Equal(thread, JSHandle<JSTaggedValue>(thread, result),
311 JSHandle<JSTaggedValue>(thread, JSTaggedValue::False())));
312 }
313 // test Has Value
314 {
315 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
316 callInfo->SetFunction(JSTaggedValue::Undefined());
317 callInfo->SetThis(lightWeightSet.GetTaggedValue());
318 callInfo->SetCallArg(0, JSTaggedValue(3));
319
320 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
321 JSTaggedValue result = ContainersLightWeightSet::Has(callInfo);
322 TestHelper::TearDownFrame(thread, prev);
323 EXPECT_TRUE(JSTaggedValue::Equal(thread, JSHandle<JSTaggedValue>(thread, result),
324 JSHandle<JSTaggedValue>(thread, JSTaggedValue::True())));
325 }
326 }
327
HWTEST_F_L0(ContainersLightWeightSetTest,Equal)328 HWTEST_F_L0(ContainersLightWeightSetTest, Equal)
329 {
330 constexpr uint32_t NODE_NUMBERS = 8; // 8 means the value
331 JSHandle<JSAPILightWeightSet> lightWeightSet = CreateJSAPILightWeightSet();
332 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
333 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
334 std::string myValue("myvalue");
335 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
336 std::string ivalue = myValue + std::to_string(i);
337 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
338 auto callInfo =
339 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value
340 callInfo->SetFunction(JSTaggedValue::Undefined());
341 callInfo->SetThis(lightWeightSet.GetTaggedValue());
342 callInfo->SetCallArg(0, value.GetTaggedValue());
343 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
344 JSTaggedValue result = ContainersLightWeightSet::Add(callInfo);
345 TestHelper::TearDownFrame(thread, prev);
346 int length = lightWeightSet->GetLength();
347 EXPECT_TRUE(JSTaggedValue::Equal(thread, JSHandle<JSTaggedValue>(thread, result),
348 JSHandle<JSTaggedValue>(thread, JSTaggedValue::True())));
349 EXPECT_EQ(length, static_cast<int>(1 + i));
350 }
351
352 JSHandle<JSAPILightWeightSet> lws = CreateJSAPILightWeightSet();
353 JSMutableHandle<JSTaggedValue> value1(thread, JSTaggedValue::Undefined());
354 myValue = "myvalue";
355 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
356 std::string ivalue = myValue + std::to_string(i);
357 value1.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
358 auto callInfo =
359 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value
360 callInfo->SetFunction(JSTaggedValue::Undefined());
361 callInfo->SetThis(lws.GetTaggedValue());
362 callInfo->SetCallArg(0, value1.GetTaggedValue());
363 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
364 JSTaggedValue result = ContainersLightWeightSet::Add(callInfo);
365 TestHelper::TearDownFrame(thread, prev);
366 int length = lws->GetLength();
367 EXPECT_TRUE(JSTaggedValue::Equal(thread, JSHandle<JSTaggedValue>(thread, result),
368 JSHandle<JSTaggedValue>(thread, JSTaggedValue::True())));
369 EXPECT_EQ(length, static_cast<int>(1 + i));
370 }
371 // test equal
372 {
373 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
374 callInfo->SetFunction(JSTaggedValue::Undefined());
375 callInfo->SetThis(lightWeightSet.GetTaggedValue());
376 callInfo->SetCallArg(0, lws.GetTaggedValue());
377
378 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
379 JSTaggedValue result = ContainersLightWeightSet::HasAll(callInfo);
380 TestHelper::TearDownFrame(thread, prev);
381 EXPECT_TRUE(JSTaggedValue::Equal(thread, JSHandle<JSTaggedValue>(thread, result),
382 JSHandle<JSTaggedValue>(thread, JSTaggedValue::True())));
383 }
384 }
385
HWTEST_F_L0(ContainersLightWeightSetTest,HasAndValuesAndEntries)386 HWTEST_F_L0(ContainersLightWeightSetTest, HasAndValuesAndEntries)
387 {
388 constexpr uint32_t NODE_NUMBERS = 8; // 8 means the value
389 JSHandle<JSAPILightWeightSet> lightWeightSet = CreateJSAPILightWeightSet();
390 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
391 auto callInfo =
392 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 4 means the value
393 callInfo->SetFunction(JSTaggedValue::Undefined());
394 callInfo->SetThis(lightWeightSet.GetTaggedValue());
395 callInfo->SetCallArg(0, JSTaggedValue(i));
396
397 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
398 JSTaggedValue result = ContainersLightWeightSet::Add(callInfo);
399 TestHelper::TearDownFrame(thread, prev);
400 int length = lightWeightSet->GetLength();
401 EXPECT_TRUE(JSTaggedValue::Equal(thread, JSHandle<JSTaggedValue>(thread, result),
402 JSHandle<JSTaggedValue>(thread, JSTaggedValue::True())));
403 EXPECT_EQ(length, static_cast<int>(i + 1));
404 }
405
406 JSMutableHandle<JSTaggedValue> result(thread, JSTaggedValue::Undefined());
407 // test values
408 auto callInfo =
409 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); // 4 means the value
410 callInfo->SetFunction(JSTaggedValue::Undefined());
411 callInfo->SetThis(lightWeightSet.GetTaggedValue());
412 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
413 JSHandle<JSTaggedValue> iterValues(thread, ContainersLightWeightSet::Values(callInfo));
414 TestHelper::TearDownFrame(thread, prev);
415 EXPECT_TRUE(iterValues->IsJSAPILightWeightSetIterator());
416
417 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
418 callInfo =
419 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); // 4 means the value
420 callInfo->SetFunction(JSTaggedValue::Undefined());
421 callInfo->SetThis(iterValues.GetTaggedValue());
422
423 prev = TestHelper::SetupFrame(thread, callInfo);
424 result.Update(JSAPILightWeightSetIterator::Next(callInfo));
425 TestHelper::TearDownFrame(thread, prev);
426 JSHandle<JSTaggedValue> ValueHandle = JSIterator::IteratorValue(thread, result);
427
428 callInfo =
429 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value
430 callInfo->SetFunction(JSTaggedValue::Undefined());
431 callInfo->SetThis(lightWeightSet.GetTaggedValue());
432 callInfo->SetCallArg(0, ValueHandle.GetTaggedValue());
433
434 prev = TestHelper::SetupFrame(thread, callInfo);
435 JSTaggedValue valueResult = ContainersLightWeightSet::Has(callInfo);
436 TestHelper::TearDownFrame(thread, prev);
437 EXPECT_EQ(valueResult, JSTaggedValue::True());
438 }
439 // test entries
440 callInfo =
441 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); // 4 means the value
442 callInfo->SetFunction(JSTaggedValue::Undefined());
443 callInfo->SetThis(lightWeightSet.GetTaggedValue());
444 prev = TestHelper::SetupFrame(thread, callInfo);
445 JSHandle<JSTaggedValue> iter(thread, ContainersLightWeightSet::Entries(callInfo));
446 TestHelper::TearDownFrame(thread, prev);
447 EXPECT_TRUE(iter->IsJSAPILightWeightSetIterator());
448
449 JSHandle<JSTaggedValue> first(thread, JSTaggedValue(0)); // 0 means the value
450 JSHandle<JSTaggedValue> second(thread, JSTaggedValue(1)); // 1 means the value
451 JSMutableHandle<JSTaggedValue> entries(thread, JSTaggedValue::Undefined());
452 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
453 callInfo =
454 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); // 4 means the value
455 callInfo->SetFunction(JSTaggedValue::Undefined());
456 callInfo->SetThis(iter.GetTaggedValue());
457
458 prev = TestHelper::SetupFrame(thread, callInfo);
459 result.Update(JSAPILightWeightSetIterator::Next(callInfo));
460 TestHelper::TearDownFrame(thread, prev);
461 entries.Update(JSIterator::IteratorValue(thread, result).GetTaggedValue());
462
463 int entriesKey = JSObject::GetProperty(thread, entries, first).GetValue()->GetInt();
464 callInfo =
465 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value
466 callInfo->SetFunction(JSTaggedValue::Undefined());
467 callInfo->SetThis(lightWeightSet.GetTaggedValue());
468 callInfo->SetCallArg(0, JSTaggedValue(entriesKey));
469 prev = TestHelper::SetupFrame(thread, callInfo);
470 JSTaggedValue keyResult = ContainersLightWeightSet::HasHash(callInfo);
471 TestHelper::TearDownFrame(thread, prev);
472 EXPECT_EQ(keyResult, JSTaggedValue::True());
473
474 int entriesValue = JSObject::GetProperty(thread, entries, second).GetValue()->GetInt();
475 callInfo =
476 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value
477 callInfo->SetFunction(JSTaggedValue::Undefined());
478 callInfo->SetThis(lightWeightSet.GetTaggedValue());
479 callInfo->SetCallArg(0, JSTaggedValue(entriesValue));
480 prev = TestHelper::SetupFrame(thread, callInfo);
481 JSTaggedValue valueResult = ContainersLightWeightSet::Has(callInfo);
482 TestHelper::TearDownFrame(thread, prev);
483 EXPECT_EQ(valueResult, JSTaggedValue::True());
484 }
485 }
486
HWTEST_F_L0(ContainersLightWeightSetTest,ForEach)487 HWTEST_F_L0(ContainersLightWeightSetTest, ForEach)
488 {
489 constexpr uint32_t NODE_NUMBERS = 8; // 8 means the value
490 JSHandle<JSAPILightWeightSet> lightWeightSet = CreateJSAPILightWeightSet();
491 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
492 auto callInfo =
493 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); // 8 means the value
494 callInfo->SetFunction(JSTaggedValue::Undefined());
495 callInfo->SetThis(lightWeightSet.GetTaggedValue());
496 callInfo->SetCallArg(0, JSTaggedValue(i));
497
498 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
499 JSTaggedValue result = ContainersLightWeightSet::Add(callInfo);
500 TestHelper::TearDownFrame(thread, prev);
501 int len = lightWeightSet->GetLength();
502 EXPECT_EQ(result, JSTaggedValue::True());
503 EXPECT_EQ(len, static_cast<int>(i + 1));
504 }
505 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
506 JSHandle<JSAPILightWeightSet> newLightWeightSet = CreateJSAPILightWeightSet();
507 {
508 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
509 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestForEachFunc));
510 auto callInfo =
511 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); // 8 means the value
512 callInfo->SetFunction(JSTaggedValue::Undefined());
513 callInfo->SetThis(lightWeightSet.GetTaggedValue());
514 callInfo->SetCallArg(0, func.GetTaggedValue());
515 callInfo->SetCallArg(1, newLightWeightSet.GetTaggedValue());
516
517 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
518 ContainersLightWeightSet::ForEach(callInfo);
519 TestHelper::TearDownFrame(thread, prev);
520 }
521
522 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
523 auto callInfo =
524 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value
525 callInfo->SetFunction(JSTaggedValue::Undefined());
526 callInfo->SetThis(lightWeightSet.GetTaggedValue());
527 callInfo->SetCallArg(0, JSTaggedValue(i));
528
529 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
530 JSTaggedValue result = ContainersLightWeightSet::GetValueAt(callInfo);
531 TestHelper::TearDownFrame(thread, prev);
532
533 callInfo =
534 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means the value
535 callInfo->SetFunction(JSTaggedValue::Undefined());
536 callInfo->SetThis(lightWeightSet.GetTaggedValue());
537 callInfo->SetCallArg(0, result);
538
539 prev = TestHelper::SetupFrame(thread, callInfo);
540 JSTaggedValue valueResult = ContainersLightWeightSet::Has(callInfo);
541 TestHelper::TearDownFrame(thread, prev);
542 EXPECT_EQ(valueResult, JSTaggedValue::True());
543 }
544 }
545
HWTEST_F_L0(ContainersLightWeightSetTest,ProxyOfGetSizeAndHasHash)546 HWTEST_F_L0(ContainersLightWeightSetTest, ProxyOfGetSizeAndHasHash)
547 {
548 constexpr uint32_t NODE_NUMBERS = 8;
549 JSHandle<JSAPILightWeightSet> lightWeightSet = CreateJSAPILightWeightSet();
550 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
551 callInfo->SetFunction(JSTaggedValue::Undefined());
552 JSHandle<JSProxy> proxy = CreateJSProxyHandle(thread);
553 proxy->SetTarget(thread, lightWeightSet.GetTaggedValue());
554 callInfo->SetThis(proxy.GetTaggedValue());
555
556 for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
557 callInfo->SetCallArg(0, JSTaggedValue(i));
558 callInfo->SetCallArg(1, JSTaggedValue(i + 1));
559 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo);
560 ContainersLightWeightSet::Add(callInfo);
561 TestHelper::TearDownFrame(thread, prev);
562
563 [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo);
564 JSTaggedValue retult = ContainersLightWeightSet::GetSize(callInfo);
565 TestHelper::TearDownFrame(thread, prev1);
566 EXPECT_EQ(retult, JSTaggedValue(i + 1));
567
568 [[maybe_unused]] auto prev2 = TestHelper::SetupFrame(thread, callInfo);
569 EXPECT_EQ(ContainersLightWeightSet::HasHash(callInfo), JSTaggedValue::True());
570 TestHelper::TearDownFrame(thread, prev2);
571 }
572 callInfo->SetCallArg(0, JSTaggedValue(NODE_NUMBERS));
573 [[maybe_unused]] auto prev2 = TestHelper::SetupFrame(thread, callInfo);
574 EXPECT_EQ(ContainersLightWeightSet::HasHash(callInfo), JSTaggedValue::False());
575 TestHelper::TearDownFrame(thread, prev2);
576 }
577
HWTEST_F_L0(ContainersLightWeightSetTest,ExceptionReturn1)578 HWTEST_F_L0(ContainersLightWeightSetTest, ExceptionReturn1)
579 {
580 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightSet, AddAll);
581 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightSet, GetValueAt);
582 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightSet, HasAll);
583 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightSet, IncreaseCapacityTo);
584 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightSet, Add);
585 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightSet, IsEmpty);
586 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightSet, Has);
587 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightSet, HasHash);
588 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightSet, Equal);
589 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightSet, GetIteratorObj);
590
591 JSHandle<JSAPILightWeightSet> lightWeightSet = CreateJSAPILightWeightSet();
592 {
593 auto callInfo = NewEmptyCallInfo(thread);
594 callInfo->SetThis(lightWeightSet.GetTaggedValue());
595 CONTAINERS_API_EXCEPTION_TEST(ContainersLightWeightSet, AddAll, callInfo);
596 }
597 {
598 auto callInfo = NewEmptyCallInfo(thread);
599 callInfo->SetThis(lightWeightSet.GetTaggedValue());
600 CONTAINERS_API_EXCEPTION_TEST(ContainersLightWeightSet, GetValueAt, callInfo);
601 }
602 {
603 auto callInfo = NewEmptyCallInfo(thread);
604 callInfo->SetThis(lightWeightSet.GetTaggedValue());
605 CONTAINERS_API_EXCEPTION_TEST(ContainersLightWeightSet, HasAll, callInfo);
606 }
607 {
608 auto callInfo = NewEmptyCallInfo(thread);
609 callInfo->SetThis(lightWeightSet.GetTaggedValue());
610 CONTAINERS_API_EXCEPTION_TEST(ContainersLightWeightSet, IncreaseCapacityTo, callInfo);
611 }
612 }
613
HWTEST_F_L0(ContainersLightWeightSetTest,ExceptionReturn2)614 HWTEST_F_L0(ContainersLightWeightSetTest, ExceptionReturn2)
615 {
616 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightSet, RemoveAt);
617 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightSet, Values);
618 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightSet, Entries);
619 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightSet, ForEach);
620 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightSet, GetIndexOf);
621 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightSet, Remove);
622 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightSet, Clear);
623 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightSet, ToString);
624 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightSet, ToArray);
625 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersLightWeightSet, GetSize);
626
627 JSHandle<JSAPILightWeightSet> lightWeightSet = CreateJSAPILightWeightSet();
628 {
629 auto callInfo = NewEmptyCallInfo(thread);
630 callInfo->SetThis(lightWeightSet.GetTaggedValue());
631 CONTAINERS_API_EXCEPTION_TEST(ContainersLightWeightSet, RemoveAt, callInfo);
632 }
633 }
634 } // namespace panda::test
635