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/js_api/js_api_queue_iterator.h"
18 #include "ecmascript/js_api/js_api_queue.h"
19 #include "ecmascript/global_env.h"
20 #include "ecmascript/tests/ecma_test_common.h"
21
22 using namespace panda;
23 using namespace panda::ecmascript;
24
25 namespace panda::test {
26 class JSAPIQueueIteratorTest : public BaseTestWithScope<false> {
27 protected:
CreateQueue(int capacaty=JSAPIQueue::DEFAULT_CAPACITY_LENGTH)28 JSHandle<JSAPIQueue> CreateQueue(int capacaty = JSAPIQueue::DEFAULT_CAPACITY_LENGTH)
29 {
30 return EcmaContainerCommon::CreateQueue(thread, capacaty);
31 }
32 };
33
34 /**
35 * @tc.name: Next
36 * @tc.desc: Create an iterator of JSAPIQueue,and then loop through the elements of the iterator to check whether
37 * the elements are consistent through Next function.
38 * @tc.type: FUNC
39 * @tc.require:
40 */
HWTEST_F_L0(JSAPIQueueIteratorTest,Next)41 HWTEST_F_L0(JSAPIQueueIteratorTest, Next)
42 {
43 constexpr uint32_t DEFAULT_LENGTH = 8;
44 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
45 JSHandle<JSAPIQueue> jsQueue = CreateQueue();
46 EXPECT_TRUE(*jsQueue != nullptr);
47 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
48 JSHandle<JSTaggedValue> valueStr = thread->GlobalConstants()->GetHandledValueString();
49 // insert value
50 std::string queueValue("keyvalue");
51 for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
52 std::string ivalue = queueValue + std::to_string(i);
53 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
54 JSAPIQueue::Add(thread, jsQueue, value);
55 }
56 JSHandle<JSAPIQueueIterator> queueIterator = factory->NewJSAPIQueueIterator(jsQueue);
57 for (uint32_t i = 0; i <= DEFAULT_LENGTH; i++) {
58 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
59 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
60 ecmaRuntimeCallInfo->SetThis(queueIterator.GetTaggedValue());
61
62 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
63 JSTaggedValue result = JSAPIQueueIterator::Next(ecmaRuntimeCallInfo);
64 TestHelper::TearDownFrame(thread, prev);
65
66 JSHandle<JSObject> resultObj(thread, result);
67 std::string resultValue = queueValue + std::to_string(i);
68 if (i <= DEFAULT_LENGTH - 1U) {
69 value.Update(factory->NewFromStdString(resultValue).GetTaggedValue());
70 EXPECT_EQ(queueIterator->GetNextIndex(), i + 1U);
71 EXPECT_EQ(JSTaggedValue::SameValue(thread,
72 JSObject::GetProperty(thread, resultObj, valueStr).GetValue(), value), true);
73 }
74 else {
75 EXPECT_TRUE(queueIterator->GetIteratedQueue(thread).IsUndefined());
76 EXPECT_TRUE(JSObject::GetProperty(thread, resultObj, valueStr).GetValue()->IsUndefined());
77 }
78 }
79 }
80
81 /**
82 * @tc.name: Next
83 * @tc.desc: test special return of Next, including throw exception and return undefined
84 * @tc.type: FUNC
85 * @tc.require:
86 */
HWTEST_F_L0(JSAPIQueueIteratorTest,SpecialReturnOfNext)87 HWTEST_F_L0(JSAPIQueueIteratorTest, SpecialReturnOfNext)
88 {
89 JSHandle<JSAPIQueue> jsQueue = CreateQueue();
90 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
91 JSHandle<JSAPIQueueIterator> queueIterator = factory->NewJSAPIQueueIterator(jsQueue);
92 queueIterator->SetIteratedQueue(thread, JSTaggedValue::Undefined());
93
94 // test Next exception
95 {
96 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
97 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
98 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
99
100 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
101 JSTaggedValue result = JSAPIQueueIterator::Next(ecmaRuntimeCallInfo);
102 TestHelper::TearDownFrame(thread, prev);
103 EXPECT_EQ(result, JSTaggedValue::Exception());
104 EXPECT_EXCEPTION();
105 }
106
107 // test Next return undefined
108 {
109 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
110 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
111 ecmaRuntimeCallInfo->SetThis(queueIterator.GetTaggedValue());
112
113 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
114 JSTaggedValue result = JSAPIQueueIterator::Next(ecmaRuntimeCallInfo);
115 TestHelper::TearDownFrame(thread, prev);
116 EXPECT_EQ(result, thread->GetEcmaVM()->GetGlobalEnv()->GetUndefinedIteratorResult().GetTaggedValue());
117 }
118 }
119
120
121 /**
122 * @tc.name: SetIteratedQueue
123 * @tc.desc: Call the "SetIteratedQueue" function, check whether the result returned through "GetIteratedQueue"
124 * function from the JSAPIQueueIterator is within expectations.
125 * @tc.type: FUNC
126 * @tc.require:
127 */
HWTEST_F_L0(JSAPIQueueIteratorTest,SetIteratedQueue)128 HWTEST_F_L0(JSAPIQueueIteratorTest, SetIteratedQueue)
129 {
130 constexpr uint32_t DEFAULT_LENGTH = 8;
131 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
132 JSHandle<JSAPIQueue> jsQueue1 = CreateQueue();
133 JSHandle<JSAPIQueue> jsQueue2 = CreateQueue();
134 EXPECT_TRUE(*jsQueue1 != nullptr);
135 EXPECT_TRUE(*jsQueue2 != nullptr);
136 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
137 // insert value
138 std::string queueValue("keyvalue");
139 for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
140 std::string ivalue = queueValue + std::to_string(i);
141 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
142 JSAPIQueue::Add(thread, jsQueue1, value);
143 }
144
145 for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
146 std::string ivalue = queueValue + std::to_string(i + 1U);
147 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
148 JSAPIQueue::Add(thread, jsQueue2, value);
149 }
150 JSHandle<JSAPIQueueIterator> queueIterator = factory->NewJSAPIQueueIterator(jsQueue1);
151 EXPECT_EQ(queueIterator->GetIteratedQueue(thread), jsQueue1.GetTaggedValue());
152
153 queueIterator->SetIteratedQueue(thread, jsQueue2.GetTaggedValue());
154 EXPECT_EQ(queueIterator->GetIteratedQueue(thread), jsQueue2.GetTaggedValue());
155 }
156
157 /**
158 * @tc.name: SetNextIndex
159 * @tc.desc: Call the "SetNextIndex" function, check whether the result returned through "GetNextIndex"
160 * function from the JSAPIQueueIterator is within expectations.
161 * @tc.type: FUNC
162 * @tc.require:
163 */
HWTEST_F_L0(JSAPIQueueIteratorTest,SetNextIndex)164 HWTEST_F_L0(JSAPIQueueIteratorTest, SetNextIndex)
165 {
166 constexpr uint32_t DEFAULT_LENGTH = 8;
167 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
168 JSHandle<JSAPIQueue> jsQueue = CreateQueue();
169 EXPECT_TRUE(*jsQueue != nullptr);
170 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
171 // insert value
172 std::string queueValue("keyvalue");
173 for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
174 std::string ivalue = queueValue + std::to_string(i);
175 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
176 JSAPIQueue::Add(thread, jsQueue, value);
177 }
178 JSHandle<JSAPIQueueIterator> queueIterator = factory->NewJSAPIQueueIterator(jsQueue);
179 for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
180 queueIterator->SetNextIndex(i);
181 EXPECT_EQ(queueIterator->GetNextIndex(), i);
182 }
183 }
184 } // namespace panda::test
185