• 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/js_api/js_api_queue.h"
17 #include "ecmascript/containers/containers_private.h"
18 #include "ecmascript/global_env.h"
19 #include "ecmascript/tests/test_helper.h"
20 
21 using namespace panda::ecmascript;
22 
23 namespace panda::test {
24 class JSAPIQueueTest : public testing::Test {
25 public:
SetUpTestCase()26     static void SetUpTestCase()
27     {
28         GTEST_LOG_(INFO) << "SetUpTestCase";
29     }
30 
TearDownTestCase()31     static void TearDownTestCase()
32     {
33         GTEST_LOG_(INFO) << "TearDownCase";
34     }
35 
SetUp()36     void SetUp() override
37     {
38         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
39     }
40 
TearDown()41     void TearDown() override
42     {
43         TestHelper::DestroyEcmaVMWithScope(instance, scope);
44     }
45 
46     EcmaVM *instance {nullptr};
47     EcmaHandleScope *scope {nullptr};
48     JSThread *thread {nullptr};
49 
50 protected:
CreateQueue(int capacaty=JSAPIQueue::DEFAULT_CAPACITY_LENGTH)51     JSHandle<JSAPIQueue> CreateQueue(int capacaty = JSAPIQueue::DEFAULT_CAPACITY_LENGTH)
52     {
53         ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
54         JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
55 
56         JSHandle<JSTaggedValue> globalObject = env->GetJSGlobalObject();
57         JSHandle<JSTaggedValue> key(factory->NewFromASCII("ArkPrivate"));
58         JSHandle<JSTaggedValue> value =
59             JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(globalObject), key).GetValue();
60 
61         auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
62         ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
63         ecmaRuntimeCallInfo->SetThis(value.GetTaggedValue());
64         ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int>(containers::ContainerTag::Queue)));
65 
66         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
67         JSTaggedValue result = containers::ContainersPrivate::Load(ecmaRuntimeCallInfo);
68         TestHelper::TearDownFrame(thread, prev);
69 
70         JSHandle<JSTaggedValue> constructor(thread, result);
71         JSHandle<JSAPIQueue> jsQueue(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
72         JSHandle<TaggedArray> newElements = factory->NewTaggedArray(capacaty);
73         jsQueue->SetElements(thread, newElements);
74         jsQueue->SetLength(thread, JSTaggedValue(0));
75         jsQueue->SetFront(0);
76         jsQueue->SetTail(0);
77         return jsQueue;
78     }
79 };
80 
HWTEST_F_L0(JSAPIQueueTest,queueCreate)81 HWTEST_F_L0(JSAPIQueueTest, queueCreate)
82 {
83     JSHandle<JSAPIQueue> jsQueue = CreateQueue();
84     EXPECT_TRUE(*jsQueue != nullptr);
85 }
86 
HWTEST_F_L0(JSAPIQueueTest,AddAndHasAndSetAndGet)87 HWTEST_F_L0(JSAPIQueueTest, AddAndHasAndSetAndGet)
88 {
89     constexpr uint32_t DEFAULT_LENGTH = 8;
90     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
91     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
92     JSHandle<JSAPIQueue> jsQueue = CreateQueue();
93 
94     std::string queueValue("queuevalue");
95     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
96         std::string ivalue = queueValue + std::to_string(i);
97         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
98         JSAPIQueue::Add(thread, jsQueue, value);
99     }
100     EXPECT_EQ(jsQueue->GetSize(), DEFAULT_LENGTH);
101     EXPECT_EQ(JSAPIQueue::GetArrayLength(thread, jsQueue), DEFAULT_LENGTH);
102 
103     // test Set, Has and Get
104     std::string ivalue = queueValue + std::to_string(10);
105     value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
106     EXPECT_FALSE(jsQueue->Has(value.GetTaggedValue()));
107     jsQueue->Set(thread, 0, value.GetTaggedValue());
108     EXPECT_EQ(jsQueue->Get(thread, 0), value.GetTaggedValue());
109     EXPECT_TRUE(jsQueue->Has(value.GetTaggedValue()));
110 
111     // test Get exception
112     JSTaggedValue result = jsQueue->Get(thread, DEFAULT_LENGTH);
113     EXPECT_EQ(result, JSTaggedValue::Exception());
114     EXPECT_EXCEPTION();
115 }
116 
HWTEST_F_L0(JSAPIQueueTest,PopFirstAndGetFirst)117 HWTEST_F_L0(JSAPIQueueTest, PopFirstAndGetFirst)
118 {
119     constexpr uint32_t DEFAULT_LENGTH = 8;
120     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
121     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
122     JSHandle<JSAPIQueue> jsQueue = CreateQueue();
123 
124     // test GetFirst and pop of empty queue
125     EXPECT_EQ(JSAPIQueue::GetFirst(thread, jsQueue), JSTaggedValue::Undefined());
126     EXPECT_EQ(JSAPIQueue::Pop(thread, jsQueue), JSTaggedValue::Undefined());
127 
128     std::string queueValue("queuevalue");
129     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
130         std::string ivalue = queueValue + std::to_string(i);
131         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
132         JSAPIQueue::Add(thread, jsQueue, value);
133     }
134 
135     // test GetFirst
136     EXPECT_EQ(JSAPIQueue::GetArrayLength(thread, jsQueue), DEFAULT_LENGTH);
137     std::string firstValue = queueValue + std::to_string(0U);
138     value.Update(factory->NewFromStdString(firstValue).GetTaggedValue());
139     EXPECT_TRUE(JSTaggedValue::SameValue(
140                 JSHandle<JSTaggedValue>(thread, JSAPIQueue::GetFirst(thread, jsQueue)), value));
141     // test Pop
142     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
143         std::string ivalue = queueValue + std::to_string(i);
144         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
145         EXPECT_TRUE(JSTaggedValue::SameValue(
146             JSHandle<JSTaggedValue>(thread, JSAPIQueue::Pop(thread, jsQueue)), value));
147         EXPECT_EQ(JSAPIQueue::GetArrayLength(thread, jsQueue), (DEFAULT_LENGTH - i - 1U));
148     }
149 }
150 
HWTEST_F_L0(JSAPIQueueTest,OwnKeys)151 HWTEST_F_L0(JSAPIQueueTest, OwnKeys)
152 {
153     constexpr uint32_t DEFAULT_LENGTH = 8;
154     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
155     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
156     JSHandle<JSAPIQueue> jsQueue = CreateQueue();
157 
158     std::string queueValue("queuevalue");
159     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
160         std::string ivalue = queueValue + std::to_string(i);
161         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
162         JSAPIQueue::Add(thread, jsQueue, value);
163     }
164     JSHandle<TaggedArray> arrayKey = JSAPIQueue::OwnKeys(thread, jsQueue);
165     EXPECT_EQ(arrayKey->GetLength(), DEFAULT_LENGTH);
166     for (int32_t i = 0; i < static_cast<int32_t>(DEFAULT_LENGTH); i++) {
167         EXPECT_EQ(arrayKey->Get(i).GetInt(), i);
168     }
169 }
170 
HWTEST_F_L0(JSAPIQueueTest,GetNextPosition)171 HWTEST_F_L0(JSAPIQueueTest, GetNextPosition)
172 {
173     constexpr uint32_t DEFAULT_LENGTH = 8;
174     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
175     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
176     JSHandle<JSAPIQueue> jsQueue = CreateQueue();
177 
178     std::string queueValue("queuevalue");
179     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
180         std::string ivalue = queueValue + std::to_string(i);
181         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
182         JSAPIQueue::Add(thread, jsQueue, value);
183     }
184     // test GetNextPosition
185     EXPECT_EQ(jsQueue->GetSize(), DEFAULT_LENGTH);
186     for (uint32_t i = 0; i < DEFAULT_LENGTH;) {
187         std::string ivalue = queueValue + std::to_string(i);
188         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
189         EXPECT_EQ(jsQueue->Get(thread, i), value.GetTaggedValue());
190         i = jsQueue->GetNextPosition(i);
191     }
192 }
193 
HWTEST_F_L0(JSAPIQueueTest,GetOwnProperty)194 HWTEST_F_L0(JSAPIQueueTest, GetOwnProperty)
195 {
196     constexpr uint32_t DEFAULT_LENGTH = 8;
197     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
198     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
199     JSHandle<JSAPIQueue> jsQueue = CreateQueue();
200 
201     std::string queueValue("queuevalue");
202     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
203         std::string ivalue = queueValue + std::to_string(i);
204         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
205         JSAPIQueue::Add(thread, jsQueue, value);
206     }
207     // test GetOwnProperty
208     int testInt = 1;
209     JSHandle<JSTaggedValue> queueKey1(thread, JSTaggedValue(testInt));
210     EXPECT_TRUE(JSAPIQueue::GetOwnProperty(thread, jsQueue, queueKey1));
211     testInt = 9;
212     JSHandle<JSTaggedValue> queueKey2(thread, JSTaggedValue(testInt));
213     EXPECT_FALSE(JSAPIQueue::GetOwnProperty(thread, jsQueue, queueKey2));
214     EXPECT_EXCEPTION();
215 
216     // test GetOwnProperty exception
217     JSHandle<JSTaggedValue> undefined(thread, JSTaggedValue::Undefined());
218     EXPECT_FALSE(JSAPIQueue::GetOwnProperty(thread, jsQueue, undefined));
219     EXPECT_EXCEPTION();
220 }
221 
222 /**
223  * @tc.name: GetProperty
224  * @tc.desc:
225  * @tc.type: FUNC
226  * @tc.require:
227  */
HWTEST_F_L0(JSAPIQueueTest,GetProperty)228 HWTEST_F_L0(JSAPIQueueTest, GetProperty)
229 {
230     JSHandle<JSAPIQueue> jsQueue = CreateQueue();
231     uint32_t elementsNums = 8;
232     for (uint32_t i = 0; i < elementsNums; i++) {
233         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
234         JSAPIQueue::Add(thread, jsQueue, value);
235     }
236     for (uint32_t i = 0; i < elementsNums; i++) {
237         JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i));
238         OperationResult getPropertyRes = JSAPIQueue::GetProperty(thread, jsQueue, key);
239         EXPECT_EQ(getPropertyRes.GetValue().GetTaggedValue(), JSTaggedValue(i));
240     }
241 }
242 
243 /**
244  * @tc.name: SetProperty
245  * @tc.desc:
246  * @tc.type: FUNC
247  * @tc.require:
248  */
HWTEST_F_L0(JSAPIQueueTest,SetProperty)249 HWTEST_F_L0(JSAPIQueueTest, SetProperty)
250 {
251     JSHandle<JSAPIQueue> jsQueue = CreateQueue();
252     uint32_t elementsNums = 8;
253     for (uint32_t i = 0; i < elementsNums; i++) {
254         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
255         JSAPIQueue::Add(thread, jsQueue, value);
256     }
257     for (uint32_t i = 0; i < elementsNums; i++) {
258         JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i));
259         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i * 2)); // 2 : It means double
260         bool setPropertyRes = JSAPIQueue::SetProperty(thread, jsQueue, key, value);
261         EXPECT_EQ(setPropertyRes, true);
262     }
263     JSHandle<JSTaggedValue> key(thread, JSTaggedValue(-1));
264     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(-1));
265     EXPECT_FALSE(JSAPIQueue::SetProperty(thread, jsQueue, key, value));
266     JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(elementsNums));
267     EXPECT_FALSE(JSAPIQueue::SetProperty(thread, jsQueue, key1, value));
268 }
269 
270 /**
271  * @tc.name: GrowCapacity
272  * @tc.desc:
273  * @tc.type: FUNC
274  * @tc.require:
275  */
HWTEST_F_L0(JSAPIQueueTest,GrowCapacity)276 HWTEST_F_L0(JSAPIQueueTest, GrowCapacity)
277 {
278     JSHandle<JSAPIQueue> jsQueue = CreateQueue(0);
279     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(0));
280     JSHandle<TaggedArray> element(thread, jsQueue->GetElements());
281     EXPECT_EQ(element->GetLength(), 0U);
282     JSAPIQueue::Add(thread, jsQueue, value);
283     JSHandle<TaggedArray> newElement(thread, jsQueue->GetElements());
284     EXPECT_EQ(newElement->GetLength(), static_cast<uint32_t>(JSAPIQueue::DEFAULT_CAPACITY_LENGTH));
285 }
286 }  // namespace panda::test