• 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_stack.h"
21 #include "ecmascript/js_api/js_api_stack_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/ecma_test_common.h"
29 
30 using namespace panda;
31 
32 using namespace panda::ecmascript;
33 
34 using namespace panda::ecmascript::containers;
35 
36 namespace panda::test {
37 class JSAPIStackTest : public BaseTestWithScope<false> {
38 protected:
CreateStack()39     JSAPIStack *CreateStack()
40     {
41         return *EcmaContainerCommon::CreateJSApiStack(thread);
42     }
43 
SearchAndEmptyCommon(JSMutableHandle<JSTaggedValue> & value,std::string & myValue,uint32_t len,bool search=false)44     JSHandle<JSAPIStack> SearchAndEmptyCommon(JSMutableHandle<JSTaggedValue>& value, std::string& myValue,
45         uint32_t len, bool search = false)
46     {
47         ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
48 
49         JSHandle<JSAPIStack> toor(thread, CreateStack());
50         for (uint32_t i = 0; i < len; i++) {
51             std::string ivalue = myValue + std::to_string(i);
52             value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
53             JSTaggedValue result = JSAPIStack::Push(thread, toor, value);
54             EXPECT_EQ(result, value.GetTaggedValue());
55             if (search) {
56                 EXPECT_EQ(toor->Search(value), static_cast<int>(i));
57             } else {
58                 EXPECT_EQ(toor->Peek(), value.GetTaggedValue());
59                 EXPECT_EQ(toor->Empty(), false);
60             }
61         }
62         return toor;
63     }
64 };
65 
HWTEST_F_L0(JSAPIStackTest,stackCreate)66 HWTEST_F_L0(JSAPIStackTest, stackCreate)
67 {
68     JSAPIStack *stack = CreateStack();
69     EXPECT_TRUE(stack != nullptr);
70 }
71 
HWTEST_F_L0(JSAPIStackTest,PushAndPeek)72 HWTEST_F_L0(JSAPIStackTest, PushAndPeek)
73 {
74     constexpr uint32_t NODE_NUMBERS = 9;
75     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
76     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
77 
78     JSHandle<JSAPIStack> toor(thread, CreateStack());
79 
80     // test Peek empty
81     EXPECT_EQ(toor->Peek(), JSTaggedValue::Undefined());
82 
83     std::string myValue("myvalue");
84     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
85         std::string ivalue = myValue + std::to_string(i);
86         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
87         JSTaggedValue result = JSAPIStack::Push(thread, toor, value);
88         EXPECT_EQ(result, value.GetTaggedValue());
89         EXPECT_EQ(toor->Peek(), value.GetTaggedValue());
90     }
91     EXPECT_EQ(static_cast<uint32_t>(toor->GetTop() + 1), NODE_NUMBERS);
92 
93     toor->Dump();
94 }
95 
HWTEST_F_L0(JSAPIStackTest,Pop)96 HWTEST_F_L0(JSAPIStackTest, Pop)
97 {
98     constexpr uint32_t NODE_NUMBERS = 9;
99     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
100     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
101 
102     JSHandle<JSAPIStack> toor(thread, CreateStack());
103 
104     // test Pop empty
105     EXPECT_EQ(toor->Pop(thread), JSTaggedValue::Undefined());
106 
107     std::string myValue("myvalue");
108     for (uint32_t i = 1; i <= NODE_NUMBERS; i++) {
109         std::string ivalue = myValue + std::to_string(i);
110         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
111         JSTaggedValue result = JSAPIStack::Push(thread, toor, value);
112         EXPECT_EQ(result, value.GetTaggedValue());
113         EXPECT_EQ(toor->Peek(), value.GetTaggedValue());
114     }
115 
116     for (uint32_t i = NODE_NUMBERS; i >= 1; i--) {
117         std::string ivalue = myValue + std::to_string(i);
118         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
119         JSTaggedValue gValue = toor->Pop(thread);
120         EXPECT_EQ(gValue, value.GetTaggedValue());
121     }
122 
123     toor->Dump();
124 }
125 
HWTEST_F_L0(JSAPIStackTest,Empty)126 HWTEST_F_L0(JSAPIStackTest, Empty)
127 {
128     constexpr uint32_t NODE_NUMBERS = 9;
129     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
130     std::string myValue("myvalue");
131     auto toor = SearchAndEmptyCommon(value, myValue, NODE_NUMBERS);
132 
133     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
134     int num = 8;
135     for (uint32_t i = 0; i < NODE_NUMBERS; i++) {
136         std::string ivalue = myValue + std::to_string(i);
137         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
138         toor->Pop(thread);
139         if (num == -1) {
140             EXPECT_EQ(toor->Empty(), true);
141         }
142     }
143 
144     toor->Dump();
145 }
146 
HWTEST_F_L0(JSAPIStackTest,Search)147 HWTEST_F_L0(JSAPIStackTest, Search)
148 {
149     constexpr uint32_t NODE_NUMBERS = 9;
150     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
151     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
152     std::string myValue("myvalue");
153     auto toor = SearchAndEmptyCommon(value, myValue, NODE_NUMBERS, true);
154     value.Update(factory->NewFromStdString(myValue).GetTaggedValue());
155     EXPECT_EQ(toor->Search(value), -1);
156 
157     toor->Dump();
158 }
159 
HWTEST_F_L0(JSAPIStackTest,GetOwnProperty)160 HWTEST_F_L0(JSAPIStackTest, GetOwnProperty)
161 {
162     constexpr uint32_t DEFAULT_LENGTH = 8;
163     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
164     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
165     JSHandle<JSAPIStack> toor(thread, CreateStack());
166 
167     std::string stackvalue("stackvalue");
168     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
169         std::string ivalue = stackvalue + std::to_string(i);
170         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
171         JSAPIStack::Push(thread, toor, value);
172     }
173     // test GetOwnProperty
174     int testInt = 1;
175     JSHandle<JSTaggedValue> stackKey1(thread, JSTaggedValue(testInt));
176     EXPECT_TRUE(JSAPIStack::GetOwnProperty(thread, toor, stackKey1));
177     testInt = 20;
178     JSHandle<JSTaggedValue> stackKey2(thread, JSTaggedValue(testInt));
179     EXPECT_FALSE(JSAPIStack::GetOwnProperty(thread, toor, stackKey2));
180     EXPECT_EXCEPTION();
181 
182     // test GetOwnProperty exception
183     JSHandle<JSTaggedValue> undefined(thread, JSTaggedValue::Undefined());
184     EXPECT_FALSE(JSAPIStack::GetOwnProperty(thread, toor, undefined));
185     EXPECT_EXCEPTION();
186 }
187 
188 /**
189  * @tc.name: GetProperty
190  * @tc.desc:
191  * @tc.type: FUNC
192  * @tc.require:
193  */
HWTEST_F_L0(JSAPIStackTest,GetProperty)194 HWTEST_F_L0(JSAPIStackTest, GetProperty)
195 {
196     JSHandle<JSAPIStack> toor(thread, CreateStack());
197     uint32_t elementsNums = 8;
198     for (uint32_t i = 0; i < elementsNums; i++) {
199         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
200         JSAPIStack::Push(thread, toor, value);
201     }
202     for (uint32_t i = 0; i < elementsNums; i++) {
203         JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i));
204         OperationResult getPropertyRes = JSAPIStack::GetProperty(thread, toor, key);
205         EXPECT_EQ(getPropertyRes.GetValue().GetTaggedValue(), JSTaggedValue(i));
206     }
207 
208     // test GetProperty Exception
209     JSHandle<JSTaggedValue> key(thread, JSTaggedValue(-1));
210     OperationResult getPropertyRes = JSAPIStack::GetProperty(thread, toor, key);
211     EXPECT_EQ(getPropertyRes.GetValue().GetTaggedValue(), JSTaggedValue::Exception());
212     EXPECT_EXCEPTION();
213 
214     JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(elementsNums));
215     OperationResult getPropertyRes1 = JSAPIStack::GetProperty(thread, toor, key1);
216     EXPECT_EQ(getPropertyRes1.GetValue().GetTaggedValue(), JSTaggedValue::Exception());
217     EXPECT_EXCEPTION();
218 }
219 
220 /**
221  * @tc.name: SetProperty
222  * @tc.desc:
223  * @tc.type: FUNC
224  * @tc.require:
225  */
HWTEST_F_L0(JSAPIStackTest,SetProperty)226 HWTEST_F_L0(JSAPIStackTest, SetProperty)
227 {
228     JSHandle<JSAPIStack> toor(thread, CreateStack());
229     uint32_t elementsNums = 8;
230     {
231         JSHandle<JSTaggedValue> key(thread, JSTaggedValue(-1));
232         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(-1));
233         EXPECT_EQ(JSTaggedValue::Undefined(), // when length = -1, return Undefine() instead of assert error
234             toor->Set(thread, key->GetInt(), value.GetTaggedValue()));
235     }
236     for (uint32_t i = 0; i < elementsNums; i++) {
237         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
238         JSAPIStack::Push(thread, toor, value);
239     }
240     for (uint32_t i = 0; i < elementsNums; i++) {
241         JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i));
242         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i * 2)); // 2 : It means double
243         bool setPropertyRes = JSAPIStack::SetProperty(thread, toor, key, value);
244         EXPECT_EQ(setPropertyRes, true);
245     }
246     JSHandle<JSTaggedValue> key(thread, JSTaggedValue(-1));
247     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(-1));
248     EXPECT_FALSE(JSAPIStack::SetProperty(thread, toor, key, value));
249     JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(elementsNums));
250     EXPECT_FALSE(JSAPIStack::SetProperty(thread, toor, key1, value));
251 }
252 
253 /**
254  * @tc.name: Has
255  * @tc.desc:
256  * @tc.type: FUNC
257  * @tc.require:
258  */
HWTEST_F_L0(JSAPIStackTest,Has)259 HWTEST_F_L0(JSAPIStackTest, Has)
260 {
261     JSHandle<JSAPIStack> toor(thread, CreateStack());
262 
263     // test Has empty
264     EXPECT_FALSE(toor->Has(JSTaggedValue(0)));
265 
266     uint32_t elementsNums = 8;
267     for (uint32_t i = 0; i < elementsNums; i++) {
268         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
269         JSAPIStack::Push(thread, toor, value);
270     }
271     for (uint32_t i = 0; i < elementsNums; i++) {
272         EXPECT_TRUE(toor->Has(JSTaggedValue(i)));
273     }
274     EXPECT_FALSE(toor->Has(JSTaggedValue(elementsNums)));
275 }
276 
277 /**
278  * @tc.name: OwnKeys
279  * @tc.desc:
280  * @tc.type: FUNC
281  * @tc.require:
282  */
HWTEST_F_L0(JSAPIStackTest,OwnKeys)283 HWTEST_F_L0(JSAPIStackTest, OwnKeys)
284 {
285     JSHandle<JSAPIStack> toor(thread, CreateStack());
286     uint32_t elementsNums = 8;
287     for (uint32_t i = 0; i < elementsNums; i++) {
288         JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i));
289         JSAPIStack::Push(thread, toor, value);
290     }
291     JSHandle<TaggedArray> keyArray = JSAPIStack::OwnKeys(thread, toor);
292     EXPECT_TRUE(keyArray->GetClass()->IsTaggedArray());
293     EXPECT_TRUE(keyArray->GetLength() == elementsNums);
294     for (uint32_t i = 0; i < elementsNums; i++) {
295         ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*(base::NumberHelper::NumberToString(thread, JSTaggedValue(i))),
296             EcmaString::Cast(keyArray->Get(i).GetTaggedObject())));
297     }
298 }
299 }  // namespace panda::test
300