• 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_deque_iterator.h"
18 #include "ecmascript/js_api/js_api_deque.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 JSAPIDequeIteratorTest : 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:
CreateJSApiDeque()53     JSAPIDeque *CreateJSApiDeque()
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 objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
64         objCallInfo->SetFunction(JSTaggedValue::Undefined());
65         objCallInfo->SetThis(value.GetTaggedValue());
66         objCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int>(containers::ContainerTag::Deque)));
67 
68         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
69         JSTaggedValue result = containers::ContainersPrivate::Load(objCallInfo);
70         TestHelper::TearDownFrame(thread, prev);
71 
72         JSHandle<JSTaggedValue> constructor(thread, result);
73         JSHandle<JSAPIDeque> deque(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
74         JSHandle<TaggedArray> newElements = factory->NewTaggedArray(JSAPIDeque::DEFAULT_CAPACITY_LENGTH);
75         deque->SetElements(thread, newElements);
76         return *deque;
77     }
78 };
79 
80 /**
81  * @tc.name: Next
82  * @tc.desc: Create an iterator of JSAPIDeque,and then loop through the elements of the iterator to check whether
83  *           the elements are consistent through Next function.
84  * @tc.type: FUNC
85  * @tc.require:
86  */
HWTEST_F_L0(JSAPIDequeIteratorTest,Next)87 HWTEST_F_L0(JSAPIDequeIteratorTest, Next)
88 {
89     constexpr uint32_t DEFAULT_LENGTH = 8;
90     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
91     JSHandle<JSAPIDeque> jsDeque(thread, CreateJSApiDeque());
92     EXPECT_TRUE(*jsDeque != nullptr);
93     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
94     JSHandle<JSTaggedValue> valueStr = thread->GlobalConstants()->GetHandledValueString();
95     // insert value
96     std::string dequeValue("keyvalue");
97     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
98         std::string ivalue = dequeValue + std::to_string(i);
99         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
100         JSAPIDeque::InsertFront(thread, jsDeque, value);
101     }
102     JSHandle<JSAPIDequeIterator> dequeIterator = factory->NewJSAPIDequeIterator(jsDeque);
103     for (uint32_t i = 0; i <= DEFAULT_LENGTH; i++) {
104         auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
105         ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
106         ecmaRuntimeCallInfo->SetThis(dequeIterator.GetTaggedValue());
107 
108         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
109         JSTaggedValue result = JSAPIDequeIterator::Next(ecmaRuntimeCallInfo);
110         TestHelper::TearDownFrame(thread, prev);
111 
112         JSHandle<JSObject> resultObj(thread, result);
113         if (i <= DEFAULT_LENGTH - 1U) {
114             EXPECT_EQ(dequeIterator->GetNextIndex(), i);
115             EXPECT_TRUE(JSObject::GetProperty(thread, resultObj, valueStr).GetValue()->IsString());
116         }
117         else {
118             EXPECT_TRUE(dequeIterator->GetIteratedDeque().IsUndefined());
119             EXPECT_TRUE(JSObject::GetProperty(thread, resultObj, valueStr).GetValue()->IsUndefined());
120         }
121     }
122 }
123 
124 /**
125  * @tc.name: Next
126  * @tc.desc: test special return of Next, including throw exception and return undefined
127  * @tc.type: FUNC
128  * @tc.require:
129  */
HWTEST_F_L0(JSAPIDequeIteratorTest,SpecialReturnOfNext)130 HWTEST_F_L0(JSAPIDequeIteratorTest, SpecialReturnOfNext)
131 {
132     JSHandle<JSAPIDeque> jsDeque(thread, CreateJSApiDeque());
133     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
134     JSHandle<JSAPIDequeIterator> dequeIterator = factory->NewJSAPIDequeIterator(jsDeque);
135     dequeIterator->SetIteratedDeque(thread, JSTaggedValue::Undefined());
136 
137     // test Next exception
138     {
139         auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
140         ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
141         ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
142 
143         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
144         JSTaggedValue result = JSAPIDequeIterator::Next(ecmaRuntimeCallInfo);
145         TestHelper::TearDownFrame(thread, prev);
146         EXPECT_EQ(result, JSTaggedValue::Exception());
147         EXPECT_EXCEPTION();
148     }
149 
150     // test Next return undefined
151     {
152         auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
153         ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
154         ecmaRuntimeCallInfo->SetThis(dequeIterator.GetTaggedValue());
155 
156         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
157         JSTaggedValue result = JSAPIDequeIterator::Next(ecmaRuntimeCallInfo);
158         TestHelper::TearDownFrame(thread, prev);
159         EXPECT_EQ(result, thread->GlobalConstants()->GetUndefinedIterResult());
160     }
161 }
162 
163 /**
164  * @tc.name: SetIteratedDeque
165  * @tc.desc: Call the "SetIteratedDeque" function, check whether the result returned through "GetIteratedDeque"
166  *           function from the JSAPIDequeIterator is within expectations.
167  * @tc.type: FUNC
168  * @tc.require:
169  */
HWTEST_F_L0(JSAPIDequeIteratorTest,SetIteratedDeque)170 HWTEST_F_L0(JSAPIDequeIteratorTest, SetIteratedDeque)
171 {
172     constexpr uint32_t DEFAULT_LENGTH = 8;
173     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
174     JSHandle<JSAPIDeque> jsDeque1(thread, CreateJSApiDeque());
175     JSHandle<JSAPIDeque> jsDeque2(thread, CreateJSApiDeque());
176     EXPECT_TRUE(*jsDeque1 != nullptr);
177     EXPECT_TRUE(*jsDeque2 != nullptr);
178     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
179     // insert value
180     std::string dequeValue("keyvalue");
181     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
182         std::string ivalue = dequeValue + std::to_string(i);
183         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
184         JSAPIDeque::InsertFront(thread, jsDeque1, value);
185     }
186 
187     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
188         std::string ivalue = dequeValue + std::to_string(i + 1U);
189         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
190         JSAPIDeque::InsertFront(thread, jsDeque2, value);
191     }
192     JSHandle<JSAPIDequeIterator> dequeIterator = factory->NewJSAPIDequeIterator(jsDeque1);
193     EXPECT_EQ(dequeIterator->GetIteratedDeque(), jsDeque1.GetTaggedValue());
194 
195     dequeIterator->SetIteratedDeque(thread, jsDeque2.GetTaggedValue());
196     EXPECT_EQ(dequeIterator->GetIteratedDeque(), jsDeque2.GetTaggedValue());
197 }
198 
199 /**
200  * @tc.name: SetNextIndex
201  * @tc.desc: Call the "SetNextIndex" function, check whether the result returned through "GetNextIndex"
202  *           function from the JSAPIDequeIterator is within expectations.
203  * @tc.type: FUNC
204  * @tc.require:
205  */
HWTEST_F_L0(JSAPIDequeIteratorTest,SetNextIndex)206 HWTEST_F_L0(JSAPIDequeIteratorTest, SetNextIndex)
207 {
208     constexpr uint32_t DEFAULT_LENGTH = 8;
209     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
210     JSHandle<JSAPIDeque> jsDeque(thread, CreateJSApiDeque());
211     EXPECT_TRUE(*jsDeque != nullptr);
212     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
213     // insert value
214     std::string dequeValue("keyvalue");
215     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
216         std::string ivalue = dequeValue + std::to_string(i);
217         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
218         JSAPIDeque::InsertFront(thread, jsDeque, value);
219     }
220     JSHandle<JSAPIDequeIterator> dequeIterator = factory->NewJSAPIDequeIterator(jsDeque);
221     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
222         dequeIterator->SetNextIndex(i);
223         EXPECT_EQ(dequeIterator->GetNextIndex(), i);
224     }
225 }
226 }  // namespace panda::test
227