• 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/ecma_string.h"
18 #include "ecmascript/ecma_vm.h"
19 #include "ecmascript/global_env.h"
20 #include "ecmascript/js_api/js_api_deque.h"
21 #include "ecmascript/js_api/js_api_deque_iterator.h"
22 #include "ecmascript/js_function.h"
23 #include "ecmascript/js_handle.h"
24 #include "ecmascript/js_iterator.h"
25 #include "ecmascript/js_object-inl.h"
26 #include "ecmascript/js_tagged_value.h"
27 #include "ecmascript/object_factory.h"
28 #include "ecmascript/tests/test_helper.h"
29 
30 using namespace panda;
31 using namespace panda::ecmascript;
32 using namespace panda::ecmascript::containers;
33 
34 namespace panda::test {
35 class JSAPIDequeTest : 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     ecmascript::EcmaHandleScope *scope {nullptr};
59     JSThread *thread {nullptr};
60 
61 protected:
CreateDeque()62     JSAPIDeque *CreateDeque()
63     {
64         ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
65         JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
66 
67         JSHandle<JSTaggedValue> globalObject = env->GetJSGlobalObject();
68         JSHandle<JSTaggedValue> key(factory->NewFromASCII("ArkPrivate"));
69         JSHandle<JSTaggedValue> value =
70             JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(globalObject), key).GetValue();
71 
72         auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
73         objCallInfo->SetFunction(JSTaggedValue::Undefined());
74         objCallInfo->SetThis(value.GetTaggedValue());
75         objCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int>(containers::ContainerTag::Deque)));
76 
77         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
78         JSTaggedValue result = containers::ContainersPrivate::Load(objCallInfo);
79         TestHelper::TearDownFrame(thread, prev);
80 
81         JSHandle<JSTaggedValue> constructor(thread, result);
82         JSHandle<JSAPIDeque> deque(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
83         JSHandle<TaggedArray> newElements = factory->NewTaggedArray(JSAPIDeque::DEFAULT_CAPACITY_LENGTH);
84         deque->SetElements(thread, newElements);
85         return *deque;
86     }
87 };
88 
HWTEST_F_L0(JSAPIDequeTest,dequeCreate)89 HWTEST_F_L0(JSAPIDequeTest, dequeCreate)
90 {
91     JSAPIDeque *deque = CreateDeque();
92     EXPECT_TRUE(deque != nullptr);
93 }
94 
HWTEST_F_L0(JSAPIDequeTest,InsertFrontAndGetFront)95 HWTEST_F_L0(JSAPIDequeTest, InsertFrontAndGetFront)
96 {
97     constexpr uint32_t NODE_NUMBERS = 9;
98     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
99     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
100 
101     JSHandle<JSAPIDeque> toor(thread, CreateDeque());
102 
103     // test GetFront of empty deque
104     EXPECT_EQ(toor->GetFront(), JSTaggedValue::Undefined());
105 
106     std::string myValue("myvalue");
107     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
108         std::string ivalue = myValue + std::to_string(i);
109         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
110         JSAPIDeque::InsertFront(thread, toor, value);
111         EXPECT_EQ(toor->GetFront(), value.GetTaggedValue());
112     }
113 
114     toor->Dump();
115 }
116 
HWTEST_F_L0(JSAPIDequeTest,InsertEndAndGetTail)117 HWTEST_F_L0(JSAPIDequeTest, InsertEndAndGetTail)
118 {
119     constexpr uint32_t NODE_NUMBERS = 9;
120     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
121     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
122 
123     JSHandle<JSAPIDeque> toor(thread, CreateDeque());
124 
125     // test GetTail of empty deque
126     EXPECT_EQ(toor->GetTail(), JSTaggedValue::Undefined());
127 
128     std::string myValue("myvalue");
129     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
130         std::string ivalue = myValue + std::to_string(i);
131         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
132         JSAPIDeque::InsertEnd(thread, toor, value);
133         EXPECT_EQ(toor->GetTail(), value.GetTaggedValue());
134     }
135 
136     toor->Dump();
137 }
138 
HWTEST_F_L0(JSAPIDequeTest,PopFirst)139 HWTEST_F_L0(JSAPIDequeTest, PopFirst)
140 {
141     constexpr uint32_t NODE_NUMBERS = 9;
142     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
143     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
144 
145     JSHandle<JSAPIDeque> toor(thread, CreateDeque());
146 
147     // test PopFirst of empty deque
148     EXPECT_EQ(toor->PopFirst(), JSTaggedValue::Undefined());
149 
150     std::string myValue("myvalue");
151     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
152         std::string ivalue = myValue + std::to_string(i);
153         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
154         JSAPIDeque::InsertFront(thread, toor, value);
155         EXPECT_EQ(toor->PopFirst(), value.GetTaggedValue());
156     }
157 
158     toor->Dump();
159 }
160 
HWTEST_F_L0(JSAPIDequeTest,PopLast)161 HWTEST_F_L0(JSAPIDequeTest, PopLast)
162 {
163     constexpr uint32_t NODE_NUMBERS = 9;
164     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
165     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
166 
167     JSHandle<JSAPIDeque> toor(thread, CreateDeque());
168 
169     // test PopLast of empty deque
170     EXPECT_EQ(toor->PopLast(), JSTaggedValue::Undefined());
171 
172     std::string myValue("myvalue");
173     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
174         std::string ivalue = myValue + std::to_string(i);
175         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
176         JSAPIDeque::InsertEnd(thread, toor, value);
177         EXPECT_EQ(toor->PopLast(), value.GetTaggedValue());
178     }
179 
180     toor->Dump();
181 }
182 
HWTEST_F_L0(JSAPIDequeTest,GetOwnProperty)183 HWTEST_F_L0(JSAPIDequeTest, GetOwnProperty)
184 {
185     constexpr uint32_t DEFAULT_LENGTH = 8;
186     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
187     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
188     JSHandle<JSAPIDeque> toor(thread, CreateDeque());
189 
190     std::string dequeValue("dequevalue");
191     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
192         std::string ivalue = dequeValue + std::to_string(i);
193         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
194         JSAPIDeque::InsertFront(thread, toor, value);
195         JSAPIDeque::InsertEnd(thread, toor, value);
196     }
197     // test GetOwnProperty
198     int testInt = 1;
199     JSHandle<JSTaggedValue> dequeKey1(thread, JSTaggedValue(testInt));
200     EXPECT_TRUE(JSAPIDeque::GetOwnProperty(thread, toor, dequeKey1));
201     testInt = 20;
202     JSHandle<JSTaggedValue> dequeKey2(thread, JSTaggedValue(testInt));
203     EXPECT_FALSE(JSAPIDeque::GetOwnProperty(thread, toor, dequeKey2));
204     EXPECT_EXCEPTION();
205 
206     // test GetOwnProperty exception
207     JSHandle<JSTaggedValue> undefined(thread, JSTaggedValue::Undefined());
208     EXPECT_FALSE(JSAPIDeque::GetOwnProperty(thread, toor, undefined));
209     EXPECT_EXCEPTION();
210 }
211 
212 /**
213  * @tc.name: GetProperty
214  * @tc.desc:
215  * @tc.type: FUNC
216  * @tc.require:
217  */
HWTEST_F_L0(JSAPIDequeTest,GetProperty)218 HWTEST_F_L0(JSAPIDequeTest, GetProperty)
219 {
220     JSHandle<JSAPIDeque> toor(thread, CreateDeque());
221     uint32_t elementsNums = 8;
222     for (uint32_t i = 0; i < elementsNums; i++) {
223         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
224         JSAPIDeque::InsertEnd(thread, toor, value);
225     }
226     for (uint32_t i = 0; i < elementsNums; i++) {
227         JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i));
228         OperationResult getPropertyRes = JSAPIDeque::GetProperty(thread, toor, key);
229         EXPECT_EQ(getPropertyRes.GetValue().GetTaggedValue(), JSTaggedValue(i));
230     }
231 }
232 
233 /**
234  * @tc.name: SetProperty
235  * @tc.desc:
236  * @tc.type: FUNC
237  * @tc.require:
238  */
HWTEST_F_L0(JSAPIDequeTest,SetProperty)239 HWTEST_F_L0(JSAPIDequeTest, SetProperty)
240 {
241     JSHandle<JSAPIDeque> toor(thread, CreateDeque());
242     uint32_t elementsNums = 8;
243     for (uint32_t i = 0; i < elementsNums; i++) {
244         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
245         JSAPIDeque::InsertFront(thread, toor, value);
246         JSAPIDeque::InsertEnd(thread, toor, value);
247     }
248     for (uint32_t i = 0; i < elementsNums; i++) {
249         JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i));
250         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i * 2)); // 2 : It means double
251         bool setPropertyRes = JSAPIDeque::SetProperty(thread, toor, key, value);
252         EXPECT_EQ(setPropertyRes, true);
253     }
254     JSHandle<JSTaggedValue> key(thread, JSTaggedValue(-1));
255     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(-1));
256     EXPECT_FALSE(JSAPIDeque::SetProperty(thread, toor, key, value));
257     JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(elementsNums * 2));
258     EXPECT_FALSE(JSAPIDeque::SetProperty(thread, toor, key1, value));
259 }
260 
261 /**
262  * @tc.name: OwnKeys
263  * @tc.desc:
264  * @tc.type: FUNC
265  * @tc.require:
266  */
HWTEST_F_L0(JSAPIDequeTest,OwnKeys)267 HWTEST_F_L0(JSAPIDequeTest, OwnKeys)
268 {
269     JSHandle<JSAPIDeque> toor(thread, CreateDeque());
270     uint32_t elementsNums = 8;
271     for (uint32_t i = 0; i < elementsNums; i++) {
272         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
273         JSAPIDeque::InsertEnd(thread, toor, value);
274     }
275 
276     // test OwnKeys
277     JSHandle<TaggedArray> keyArray = JSAPIDeque::OwnKeys(thread, toor);
278     EXPECT_TRUE(keyArray->GetClass()->IsTaggedArray());
279     EXPECT_TRUE(keyArray->GetLength() == elementsNums);
280     for (uint32_t i = 0; i < elementsNums; i++) {
281         ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*(base::NumberHelper::NumberToString(thread, JSTaggedValue(i))),
282             EcmaString::Cast(keyArray->Get(i).GetTaggedObject())));
283     }
284 }
285 }  // namespace panda::test
286