• 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         ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*(base::NumberHelper::NumberToString(thread, JSTaggedValue(i))),
168             EcmaString::Cast(arrayKey->Get(i).GetTaggedObject())));
169     }
170 }
171 
HWTEST_F_L0(JSAPIQueueTest,GetNextPosition)172 HWTEST_F_L0(JSAPIQueueTest, GetNextPosition)
173 {
174     constexpr uint32_t DEFAULT_LENGTH = 8;
175     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
176     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
177     JSHandle<JSAPIQueue> jsQueue = CreateQueue();
178 
179     std::string queueValue("queuevalue");
180     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
181         std::string ivalue = queueValue + std::to_string(i);
182         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
183         JSAPIQueue::Add(thread, jsQueue, value);
184     }
185     // test GetNextPosition
186     EXPECT_EQ(jsQueue->GetSize(), DEFAULT_LENGTH);
187     for (uint32_t i = 0; i < DEFAULT_LENGTH;) {
188         std::string ivalue = queueValue + std::to_string(i);
189         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
190         EXPECT_EQ(jsQueue->Get(thread, i), value.GetTaggedValue());
191         i = jsQueue->GetNextPosition(i);
192     }
193 }
194 
HWTEST_F_L0(JSAPIQueueTest,GetOwnProperty)195 HWTEST_F_L0(JSAPIQueueTest, GetOwnProperty)
196 {
197     constexpr uint32_t DEFAULT_LENGTH = 8;
198     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
199     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
200     JSHandle<JSAPIQueue> jsQueue = CreateQueue();
201 
202     std::string queueValue("queuevalue");
203     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
204         std::string ivalue = queueValue + std::to_string(i);
205         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
206         JSAPIQueue::Add(thread, jsQueue, value);
207     }
208     // test GetOwnProperty
209     int testInt = 1;
210     JSHandle<JSTaggedValue> queueKey1(thread, JSTaggedValue(testInt));
211     EXPECT_TRUE(JSAPIQueue::GetOwnProperty(thread, jsQueue, queueKey1));
212     testInt = 9;
213     JSHandle<JSTaggedValue> queueKey2(thread, JSTaggedValue(testInt));
214     EXPECT_FALSE(JSAPIQueue::GetOwnProperty(thread, jsQueue, queueKey2));
215     EXPECT_EXCEPTION();
216 
217     // test GetOwnProperty exception
218     JSHandle<JSTaggedValue> undefined(thread, JSTaggedValue::Undefined());
219     EXPECT_FALSE(JSAPIQueue::GetOwnProperty(thread, jsQueue, undefined));
220     EXPECT_EXCEPTION();
221 }
222 
223 /**
224  * @tc.name: GetProperty
225  * @tc.desc:
226  * @tc.type: FUNC
227  * @tc.require:
228  */
HWTEST_F_L0(JSAPIQueueTest,GetProperty)229 HWTEST_F_L0(JSAPIQueueTest, GetProperty)
230 {
231     JSHandle<JSAPIQueue> jsQueue = CreateQueue();
232     uint32_t elementsNums = 8;
233     for (uint32_t i = 0; i < elementsNums; i++) {
234         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
235         JSAPIQueue::Add(thread, jsQueue, value);
236     }
237     for (uint32_t i = 0; i < elementsNums; i++) {
238         JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i));
239         OperationResult getPropertyRes = JSAPIQueue::GetProperty(thread, jsQueue, key);
240         EXPECT_EQ(getPropertyRes.GetValue().GetTaggedValue(), JSTaggedValue(i));
241     }
242 }
243 
244 /**
245  * @tc.name: SetProperty
246  * @tc.desc:
247  * @tc.type: FUNC
248  * @tc.require:
249  */
HWTEST_F_L0(JSAPIQueueTest,SetProperty)250 HWTEST_F_L0(JSAPIQueueTest, SetProperty)
251 {
252     JSHandle<JSAPIQueue> jsQueue = CreateQueue();
253     uint32_t elementsNums = 8;
254     for (uint32_t i = 0; i < elementsNums; i++) {
255         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
256         JSAPIQueue::Add(thread, jsQueue, value);
257     }
258     for (uint32_t i = 0; i < elementsNums; i++) {
259         JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i));
260         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i * 2)); // 2 : It means double
261         bool setPropertyRes = JSAPIQueue::SetProperty(thread, jsQueue, key, value);
262         EXPECT_EQ(setPropertyRes, true);
263     }
264     JSHandle<JSTaggedValue> key(thread, JSTaggedValue(-1));
265     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(-1));
266     EXPECT_FALSE(JSAPIQueue::SetProperty(thread, jsQueue, key, value));
267     JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(elementsNums));
268     EXPECT_FALSE(JSAPIQueue::SetProperty(thread, jsQueue, key1, value));
269 }
270 
271 /**
272  * @tc.name: GrowCapacity
273  * @tc.desc:
274  * @tc.type: FUNC
275  * @tc.require:
276  */
HWTEST_F_L0(JSAPIQueueTest,GrowCapacity)277 HWTEST_F_L0(JSAPIQueueTest, GrowCapacity)
278 {
279     JSHandle<JSAPIQueue> jsQueue = CreateQueue(0);
280     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(0));
281     JSHandle<TaggedArray> element(thread, jsQueue->GetElements());
282     EXPECT_EQ(element->GetLength(), 0U);
283     JSAPIQueue::Add(thread, jsQueue, value);
284     JSHandle<TaggedArray> newElement(thread, jsQueue->GetElements());
285     EXPECT_EQ(newElement->GetLength(), static_cast<uint32_t>(JSAPIQueue::DEFAULT_CAPACITY_LENGTH));
286 }
287 }  // namespace panda::test