• 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_stack_iterator.h"
17 #include "ecmascript/containers/containers_private.h"
18 #include "ecmascript/global_env.h"
19 #include "ecmascript/js_api/js_api_stack.h"
20 #include "ecmascript/tests/ecma_test_common.h"
21 
22 using namespace panda::ecmascript;
23 using namespace panda::ecmascript::containers;
24 
25 namespace panda::test {
26 class JSAPIStackIteratorTest : public BaseTestWithScope<false> {
27 protected:
CreateJSApiStack(JSThread * thread)28     static JSHandle<JSAPIStack> CreateJSApiStack(JSThread *thread)
29     {
30         return EcmaContainerCommon::CreateJSApiStack(thread);
31     }
32 };
33 
34 /**
35  * @tc.name: Next
36  * @tc.desc: Create an iterator of JSAPIStack,and then loop through the elements of the iterator to check whether
37  *           the elements are consistent through Next function.
38  * @tc.type: FUNC
39  * @tc.require:
40  */
HWTEST_F_L0(JSAPIStackIteratorTest,Next)41 HWTEST_F_L0(JSAPIStackIteratorTest, Next)
42 {
43     constexpr uint32_t DEFAULT_LENGTH = 9;
44     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
45     JSHandle<JSAPIStack> jsStack = CreateJSApiStack(thread);
46     EXPECT_TRUE(*jsStack != nullptr);
47     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
48     JSHandle<JSTaggedValue> valueStr = thread->GlobalConstants()->GetHandledValueString();
49     // insert value
50     std::string stackValue("keyvalue");
51     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
52         std::string ivalue = stackValue + std::to_string(i);
53         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
54         JSAPIStack::Push(thread, jsStack, value);
55     }
56     JSHandle<JSAPIStackIterator> stackIterator = factory->NewJSAPIStackIterator(jsStack);
57     for (uint32_t i = 0; i <= DEFAULT_LENGTH; i++) {
58         auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
59         ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
60         ecmaRuntimeCallInfo->SetThis(stackIterator.GetTaggedValue());
61 
62         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
63         JSTaggedValue result = JSAPIStackIterator::Next(ecmaRuntimeCallInfo);
64         TestHelper::TearDownFrame(thread, prev);
65 
66         JSHandle<JSObject> resultObj(thread, result);
67         if (i <= DEFAULT_LENGTH - 1U) {
68             EXPECT_EQ(stackIterator->GetNextIndex(), (i + 1U));
69             EXPECT_TRUE(JSObject::GetProperty(thread, resultObj, valueStr).GetValue()->IsString());
70         }
71         else {
72             EXPECT_TRUE(stackIterator->GetIteratedStack().IsUndefined());
73             EXPECT_TRUE(JSObject::GetProperty(thread, resultObj, valueStr).GetValue()->IsUndefined());
74         }
75     }
76 }
77 
78 /**
79  * @tc.name: Next
80  * @tc.desc: test special return of Next, including throw exception and return undefined
81  * @tc.type: FUNC
82  * @tc.require:
83  */
HWTEST_F_L0(JSAPIStackIteratorTest,SpecialReturnOfNext)84 HWTEST_F_L0(JSAPIStackIteratorTest, SpecialReturnOfNext)
85 {
86     JSHandle<JSAPIStack> jsStack = CreateJSApiStack(thread);
87     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
88     JSHandle<JSAPIStackIterator> stackIterator = factory->NewJSAPIStackIterator(jsStack);
89     stackIterator->SetIteratedStack(thread, JSTaggedValue::Undefined());
90 
91     // test Next exception
92     {
93         auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
94         ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
95         ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
96 
97         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
98         JSTaggedValue result = JSAPIStackIterator::Next(ecmaRuntimeCallInfo);
99         TestHelper::TearDownFrame(thread, prev);
100         EXPECT_EQ(result, JSTaggedValue::Exception());
101         EXPECT_EXCEPTION();
102     }
103 
104     // test Next return undefined
105     {
106         auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
107         ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
108         ecmaRuntimeCallInfo->SetThis(stackIterator.GetTaggedValue());
109 
110         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
111         JSTaggedValue result = JSAPIStackIterator::Next(ecmaRuntimeCallInfo);
112         TestHelper::TearDownFrame(thread, prev);
113         EXPECT_EQ(result, thread->GlobalConstants()->GetUndefinedIterResult());
114     }
115 }
116 
117 /**
118  * @tc.name: SetIteratedStack
119  * @tc.desc: Call the "SetIteratedStack" function, check whether the result returned through "GetIteratedStack"
120  *           function from the JSAPIStackIterator is within expectations.
121  * @tc.type: FUNC
122  * @tc.require:
123  */
HWTEST_F_L0(JSAPIStackIteratorTest,SetIteratedStack)124 HWTEST_F_L0(JSAPIStackIteratorTest, SetIteratedStack)
125 {
126     constexpr uint32_t DEFAULT_LENGTH = 9;
127     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
128     JSHandle<JSAPIStack> jsStack1 = CreateJSApiStack(thread);
129     JSHandle<JSAPIStack> jsStack2 = CreateJSApiStack(thread);
130     EXPECT_TRUE(*jsStack1 != nullptr);
131     EXPECT_TRUE(*jsStack2 != nullptr);
132     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
133     // insert value
134     std::string stackValue("keyvalue");
135     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
136         std::string ivalue = stackValue + std::to_string(i);
137         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
138         JSAPIStack::Push(thread, jsStack1, value);
139     }
140 
141     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
142         std::string ivalue = stackValue + std::to_string(i + 2U);
143         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
144         JSAPIStack::Push(thread, jsStack2, value);
145     }
146     JSHandle<JSAPIStackIterator> stackIterator = factory->NewJSAPIStackIterator(jsStack1);
147     EXPECT_EQ(stackIterator->GetIteratedStack(), jsStack1.GetTaggedValue());
148 
149     stackIterator->SetIteratedStack(thread, jsStack2.GetTaggedValue());
150     JSHandle<JSAPIStack> jsAPIStackTo(thread, JSAPIStack::Cast(stackIterator->GetIteratedStack().GetTaggedObject()));
151     EXPECT_EQ(jsAPIStackTo->GetSize(), static_cast<int>(DEFAULT_LENGTH - 1U));
152 
153     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
154         std::string ivalue = stackValue + std::to_string(i + 2U);
155         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
156         EXPECT_EQ(jsAPIStackTo->Search(value), static_cast<int>(i));
157     }
158 }
159 
160 /**
161  * @tc.name: SetNextIndex
162  * @tc.desc: Call the "SetNextIndex" function, check whether the result returned through "GetNextIndex"
163  *           function from the JSAPIStackIterator is within expectations.
164  * @tc.type: FUNC
165  * @tc.require:
166  */
HWTEST_F_L0(JSAPIStackIteratorTest,SetNextIndex)167 HWTEST_F_L0(JSAPIStackIteratorTest, SetNextIndex)
168 {
169     constexpr uint32_t DEFAULT_LENGTH = 9;
170     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
171     JSHandle<JSAPIStack> jsStack = CreateJSApiStack(thread);
172     EXPECT_TRUE(*jsStack != nullptr);
173     JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined());
174     // insert value
175     std::string stackValue("keyvalue");
176     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
177         std::string ivalue = stackValue + std::to_string(i);
178         value.Update(factory->NewFromStdString(ivalue).GetTaggedValue());
179         JSAPIStack::Push(thread, jsStack, value);
180     }
181     JSHandle<JSAPIStackIterator> stackIterator = factory->NewJSAPIStackIterator(jsStack);
182     EXPECT_EQ(stackIterator->GetNextIndex(), 0U);
183 
184     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
185         stackIterator->SetNextIndex(i);
186         EXPECT_EQ(stackIterator->GetNextIndex(), i);
187     }
188 }
189 }  // namespace panda::ecmascript
190