• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/test_helper.h"
21 
22 using namespace panda;
23 using namespace panda::ecmascript;
24 
25 namespace panda::test {
26 class JSAPIQueueIteratorTest : public testing::Test {
27 public:
SetUpTestCase()28     static void SetUpTestCase()
29     {
30         GTEST_LOG_(INFO) << "SetUpTestCase";
31     }
32 
TearDownTestCase()33     static void TearDownTestCase()
34     {
35         GTEST_LOG_(INFO) << "TearDownCase";
36     }
37 
SetUp()38     void SetUp() override
39     {
40         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
41     }
42 
TearDown()43     void TearDown() override
44     {
45         TestHelper::DestroyEcmaVMWithScope(instance, scope);
46     }
47 
48     EcmaVM *instance {nullptr};
49     ecmascript::EcmaHandleScope *scope {nullptr};
50     JSThread *thread {nullptr};
51 
52 protected:
CreateQueue(int capacaty=JSAPIQueue::DEFAULT_CAPACITY_LENGTH)53     JSHandle<JSAPIQueue> CreateQueue(int capacaty = JSAPIQueue::DEFAULT_CAPACITY_LENGTH)
54     {
55         ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
56         JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
57 
58         JSHandle<JSTaggedValue> globalObject = env->GetJSGlobalObject();
59         JSHandle<JSTaggedValue> key(factory->NewFromASCII("ArkPrivate"));
60         JSHandle<JSTaggedValue> value =
61             JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(globalObject), key).GetValue();
62 
63         auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
64         ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
65         ecmaRuntimeCallInfo->SetThis(value.GetTaggedValue());
66         ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int>(containers::ContainerTag::Queue)));
67 
68         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
69         JSTaggedValue result = containers::ContainersPrivate::Load(ecmaRuntimeCallInfo);
70         TestHelper::TearDownFrame(thread, prev);
71 
72         JSHandle<JSTaggedValue> constructor(thread, result);
73         JSHandle<JSAPIQueue> jsQueue(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
74         JSHandle<TaggedArray> newElements = factory->NewTaggedArray(capacaty);
75         jsQueue->SetElements(thread, newElements);
76         jsQueue->SetLength(thread, JSTaggedValue(0));
77         jsQueue->SetFront(0);
78         jsQueue->SetTail(0);
79         return jsQueue;
80     }
81 };
82 
83 /**
84  * @tc.name: Next
85  * @tc.desc: Create an iterator of JSAPIQueue,and then loop through the elements of the iterator to check whether
86  *           the elements are consistent through Next function.
87  * @tc.type: FUNC
88  * @tc.require:
89  */
HWTEST_F_L0(JSAPIQueueIteratorTest,Next)90 HWTEST_F_L0(JSAPIQueueIteratorTest, Next)
91 {
92     constexpr uint32_t DEFAULT_LENGTH = 8;
93     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
94     JSHandle<JSAPIQueue> jsQueue = CreateQueue();
95     EXPECT_TRUE(*jsQueue != nullptr);
96     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
97     JSHandle<JSTaggedValue> valueStr = thread->GlobalConstants()->GetHandledValueString();
98     // insert value
99     std::string queueValue("keyvalue");
100     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
101         std::string ivalue = queueValue + std::to_string(i);
102         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
103         JSAPIQueue::Add(thread, jsQueue, value);
104     }
105     JSHandle<JSAPIQueueIterator> queueIterator = factory->NewJSAPIQueueIterator(jsQueue);
106     for (uint32_t i = 0; i <= DEFAULT_LENGTH; i++) {
107         auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
108         ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
109         ecmaRuntimeCallInfo->SetThis(queueIterator.GetTaggedValue());
110 
111         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
112         JSTaggedValue result = JSAPIQueueIterator::Next(ecmaRuntimeCallInfo);
113         TestHelper::TearDownFrame(thread, prev);
114 
115         JSHandle<JSObject> resultObj(thread, result);
116         std::string resultValue = queueValue + std::to_string(i);
117         if (i <= DEFAULT_LENGTH - 1U) {
118             value.Update(factory->NewFromStdString(resultValue).GetTaggedValue());
119             EXPECT_EQ(queueIterator->GetNextIndex(), i + 1U);
120             EXPECT_EQ(JSTaggedValue::SameValue(
121             JSObject::GetProperty(thread, resultObj, valueStr).GetValue(), value), true);
122         }
123         else {
124             EXPECT_TRUE(queueIterator->GetIteratedQueue().IsUndefined());
125             EXPECT_TRUE(JSObject::GetProperty(thread, resultObj, valueStr).GetValue()->IsUndefined());
126         }
127     }
128 }
129 
130 /**
131  * @tc.name: Next
132  * @tc.desc: test special return of Next, including throw exception and return undefined
133  * @tc.type: FUNC
134  * @tc.require:
135  */
HWTEST_F_L0(JSAPIQueueIteratorTest,SpecialReturnOfNext)136 HWTEST_F_L0(JSAPIQueueIteratorTest, SpecialReturnOfNext)
137 {
138     JSHandle<JSAPIQueue> jsQueue = CreateQueue();
139     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
140     JSHandle<JSAPIQueueIterator> queueIterator = factory->NewJSAPIQueueIterator(jsQueue);
141     queueIterator->SetIteratedQueue(thread, JSTaggedValue::Undefined());
142 
143     // test Next exception
144     {
145         auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
146         ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
147         ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
148 
149         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
150         JSTaggedValue result = JSAPIQueueIterator::Next(ecmaRuntimeCallInfo);
151         TestHelper::TearDownFrame(thread, prev);
152         EXPECT_EQ(result, JSTaggedValue::Exception());
153         EXPECT_EXCEPTION();
154     }
155 
156     // test Next return undefined
157     {
158         auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
159         ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
160         ecmaRuntimeCallInfo->SetThis(queueIterator.GetTaggedValue());
161 
162         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
163         JSTaggedValue result = JSAPIQueueIterator::Next(ecmaRuntimeCallInfo);
164         TestHelper::TearDownFrame(thread, prev);
165         EXPECT_EQ(result, thread->GlobalConstants()->GetUndefinedIterResult());
166     }
167 }
168 
169 
170 /**
171  * @tc.name: SetIteratedQueue
172  * @tc.desc: Call the "SetIteratedQueue" function, check whether the result returned through "GetIteratedQueue"
173  *           function from the JSAPIQueueIterator is within expectations.
174  * @tc.type: FUNC
175  * @tc.require:
176  */
HWTEST_F_L0(JSAPIQueueIteratorTest,SetIteratedQueue)177 HWTEST_F_L0(JSAPIQueueIteratorTest, SetIteratedQueue)
178 {
179     constexpr uint32_t DEFAULT_LENGTH = 8;
180     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
181     JSHandle<JSAPIQueue> jsQueue1 = CreateQueue();
182     JSHandle<JSAPIQueue> jsQueue2 = CreateQueue();
183     EXPECT_TRUE(*jsQueue1 != nullptr);
184     EXPECT_TRUE(*jsQueue2 != nullptr);
185     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
186     // insert value
187     std::string queueValue("keyvalue");
188     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
189         std::string ivalue = queueValue + std::to_string(i);
190         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
191         JSAPIQueue::Add(thread, jsQueue1, value);
192     }
193 
194     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
195         std::string ivalue = queueValue + std::to_string(i + 1U);
196         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
197         JSAPIQueue::Add(thread, jsQueue2, value);
198     }
199     JSHandle<JSAPIQueueIterator> queueIterator = factory->NewJSAPIQueueIterator(jsQueue1);
200     EXPECT_EQ(queueIterator->GetIteratedQueue(), jsQueue1.GetTaggedValue());
201 
202     queueIterator->SetIteratedQueue(thread, jsQueue2.GetTaggedValue());
203     EXPECT_EQ(queueIterator->GetIteratedQueue(), jsQueue2.GetTaggedValue());
204 }
205 
206 /**
207  * @tc.name: SetNextIndex
208  * @tc.desc: Call the "SetNextIndex" function, check whether the result returned through "GetNextIndex"
209  *           function from the JSAPIQueueIterator is within expectations.
210  * @tc.type: FUNC
211  * @tc.require:
212  */
HWTEST_F_L0(JSAPIQueueIteratorTest,SetNextIndex)213 HWTEST_F_L0(JSAPIQueueIteratorTest, SetNextIndex)
214 {
215     constexpr uint32_t DEFAULT_LENGTH = 8;
216     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
217     JSHandle<JSAPIQueue> jsQueue = CreateQueue();
218     EXPECT_TRUE(*jsQueue != nullptr);
219     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
220     // insert value
221     std::string queueValue("keyvalue");
222     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
223         std::string ivalue = queueValue + std::to_string(i);
224         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
225         JSAPIQueue::Add(thread, jsQueue, value);
226     }
227     JSHandle<JSAPIQueueIterator> queueIterator = factory->NewJSAPIQueueIterator(jsQueue);
228     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
229         queueIterator->SetNextIndex(i);
230         EXPECT_EQ(queueIterator->GetNextIndex(), i);
231     }
232 }
233 }  // namespace panda::test
234