• 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_tree_set_iterator.h"
17 #include "ecmascript/containers/containers_private.h"
18 #include "ecmascript/global_env.h"
19 #include "ecmascript/js_api/js_api_tree_set.h"
20 #include "ecmascript/js_iterator.h"
21 #include "ecmascript/tagged_tree.h"
22 #include "ecmascript/tests/ecma_test_common.h"
23 
24 using namespace panda;
25 using namespace panda::ecmascript;
26 
27 namespace panda::test {
28 class JSAPITreeSetIteratorTest : public BaseTestWithScope<false> {
29 protected:
CreateTreeSet()30     JSHandle<JSAPITreeSet> CreateTreeSet()
31     {
32         ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
33         auto result = TestCommon::CreateContainerTaggedValue(thread, containers::ContainerTag::TreeSet);
34         JSHandle<JSTaggedValue> constructor(thread, result);
35         JSHandle<JSAPITreeSet> set(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
36         JSTaggedValue internal = TaggedTreeSet::Create(thread);
37         set->SetTreeSet(thread, internal);
38         return set;
39     }
40 };
41 
42 /**
43  * @tc.name: SetIterationKind
44  * @tc.desc: Call the "SetIterationKind" function, check whether the result returned through "GetIterationKind"
45  *           function from the JSAPITreeSetIterator is within expectations.
46  * @tc.type: FUNC
47  * @tc.require:
48  */
HWTEST_F_L0(JSAPITreeSetIteratorTest,SetIterationKind)49 HWTEST_F_L0(JSAPITreeSetIteratorTest, SetIterationKind)
50 {
51     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
52     JSHandle<JSAPITreeSet> jsTreeSet = CreateTreeSet();
53     EXPECT_TRUE(*jsTreeSet != nullptr);
54     JSHandle<JSAPITreeSetIterator> treeSetIterator =
55         factory->NewJSAPITreeSetIterator(jsTreeSet, IterationKind::KEY);
56     EXPECT_EQ(treeSetIterator->GetIterationKind(), IterationKind::KEY);
57     treeSetIterator->SetIterationKind(IterationKind::VALUE);
58     EXPECT_EQ(treeSetIterator->GetIterationKind(), IterationKind::VALUE);
59     treeSetIterator->SetIterationKind(IterationKind::KEY_AND_VALUE);
60     EXPECT_EQ(treeSetIterator->GetIterationKind(), IterationKind::KEY_AND_VALUE);
61 }
62 
63 /**
64  * @tc.name: SetIteratedSet
65  * @tc.desc: Call the "SetIteratedSet" function, check whether the result returned through "GetIteratedSet"
66  *           function from the JSAPITreeSetIterator is within expectations.
67  * @tc.type: FUNC
68  * @tc.require:
69  */
HWTEST_F_L0(JSAPITreeSetIteratorTest,SetIteratedSet)70 HWTEST_F_L0(JSAPITreeSetIteratorTest, SetIteratedSet)
71 {
72     constexpr uint32_t DEFAULT_LENGTH = 8;
73     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
74     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
75     JSHandle<JSAPITreeSet> jsTreeSet = CreateTreeSet();
76     EXPECT_TRUE(*jsTreeSet != nullptr);
77     JSHandle<JSAPITreeSetIterator> treeSetIterator =
78         factory->NewJSAPITreeSetIterator(jsTreeSet, IterationKind::VALUE);
79 
80     std::string setKey("setkey");
81     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
82         std::string ikey = setKey + std::to_string(i);
83         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
84         JSAPITreeSet::Add(thread, jsTreeSet, key);
85     }
86     treeSetIterator->SetIteratedSet(thread, jsTreeSet.GetTaggedValue());
87     JSHandle<JSAPITreeSet> treeSetTo(thread,
88                                      JSAPITreeSet::Cast(treeSetIterator->GetIteratedSet(thread).GetTaggedObject()));
89     EXPECT_EQ(treeSetTo->GetSize(thread), static_cast<int>(DEFAULT_LENGTH));
90     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
91         std::string ikey = setKey + std::to_string(i);
92         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
93         EXPECT_TRUE(JSAPITreeSet::Has(thread, jsTreeSet, key));
94     }
95 }
96 
97 /**
98  * @tc.name: SetNextIndex
99  * @tc.desc: Call the "SetNextIndex" function, check whether the result returned through "GetNextIndex"
100  *           function from the JSAPITreeSetIterator is within expectations.
101  * @tc.type: FUNC
102  * @tc.require:
103  */
HWTEST_F_L0(JSAPITreeSetIteratorTest,SetNextIndex)104 HWTEST_F_L0(JSAPITreeSetIteratorTest, SetNextIndex)
105 {
106     constexpr uint32_t DEFAULT_LENGTH = 8;
107     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
108     JSHandle<JSAPITreeSet> jsTreeSet = CreateTreeSet();
109     EXPECT_TRUE(*jsTreeSet != nullptr);
110     JSHandle<JSAPITreeSetIterator> treeSetIterator =
111         factory->NewJSAPITreeSetIterator(jsTreeSet, IterationKind::KEY_AND_VALUE);
112     EXPECT_EQ(treeSetIterator->GetNextIndex(), 0U);
113 
114     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
115         treeSetIterator->SetNextIndex(i);
116         EXPECT_EQ(treeSetIterator->GetNextIndex(), i);
117     }
118 }
119 
120 /**
121  * @tc.name: CreateTreeSetIterator
122  * @tc.desc: Create TreeSet iterator, check whether the result returned through "IsJSAPITreeSetIterator"
123  *           function from the JSAPITreeSetIterator is within expectations.
124  * @tc.type: FUNC
125  * @tc.require:
126  */
HWTEST_F_L0(JSAPITreeSetIteratorTest,CreateTreeSetIterator)127 HWTEST_F_L0(JSAPITreeSetIteratorTest, CreateTreeSetIterator)
128 {
129     JSHandle<JSAPITreeSet> jsTreeSet = CreateTreeSet();
130     EXPECT_TRUE(*jsTreeSet != nullptr);
131     JSHandle<JSTaggedValue> treeSetVal(jsTreeSet);
132     // Create Iterator with KEY
133     JSHandle<JSTaggedValue> treeSetIterator =
134         JSAPITreeSetIterator::CreateTreeSetIterator(thread, treeSetVal, IterationKind::KEY);
135     EXPECT_TRUE(*treeSetIterator != nullptr);
136     EXPECT_TRUE(treeSetIterator->IsJSAPITreeSetIterator());
137     // Create Iterator with VALUE
138     treeSetIterator = JSAPITreeSetIterator::CreateTreeSetIterator(thread, treeSetVal, IterationKind::VALUE);
139     EXPECT_TRUE(*treeSetIterator != nullptr);
140     EXPECT_TRUE(treeSetIterator->IsJSAPITreeSetIterator());
141     // Create Iterator with KEY_AND_VALUE
142     treeSetIterator = JSAPITreeSetIterator::CreateTreeSetIterator(thread, treeSetVal, IterationKind::KEY_AND_VALUE);
143     EXPECT_TRUE(*treeSetIterator != nullptr);
144     EXPECT_TRUE(treeSetIterator->IsJSAPITreeSetIterator());
145 }
146 
147 /**
148  * @tc.name: Next
149  * @tc.desc: Create an iterator of JSAPITreeSet,and then loop through the elements(key and keyAndvalue) of the
150  *           iterator to check whether the elements through "Next" function are consistent.
151  * @tc.type: FUNC
152  * @tc.require:
153  */
HWTEST_F_L0(JSAPITreeSetIteratorTest,KEY_Next)154 HWTEST_F_L0(JSAPITreeSetIteratorTest, KEY_Next)
155 {
156     constexpr uint32_t DEFAULT_LENGTH = 8;
157     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
158     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
159     JSHandle<JSTaggedValue> valueStr = thread->GlobalConstants()->GetHandledValueString();
160     JSHandle<JSAPITreeSet> jsTreeSet = CreateTreeSet();
161     std::string setKey("setkey");
162     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
163         std::string ikey = setKey + std::to_string(i);
164         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
165         JSAPITreeSet::Add(thread, jsTreeSet, key);
166     }
167     // Create Iterator with KEY or VALUE
168     JSHandle<JSAPITreeSetIterator> treeSetIterator =
169         factory->NewJSAPITreeSetIterator(jsTreeSet, IterationKind::KEY);
170     // traversal iterator
171     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
172         auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
173         ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
174         ecmaRuntimeCallInfo->SetThis(treeSetIterator.GetTaggedValue());
175 
176         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
177         JSTaggedValue result = JSAPITreeSetIterator::Next(ecmaRuntimeCallInfo);
178         TestHelper::TearDownFrame(thread, prev);
179 
180         JSHandle<JSObject> resultObj(thread, result);
181         std::string resultKey = setKey + std::to_string(i);
182         key.Update(factory->NewFromStdString(resultKey).GetTaggedValue());
183         EXPECT_EQ(JSTaggedValue::SameValue(thread,
184             JSObject::GetProperty(thread, resultObj, valueStr).GetValue(), key), true);
185         EXPECT_EQ(treeSetIterator->GetNextIndex(), (i + 1U));
186     }
187 }
188 
189 /**
190  * @tc.name: Next
191  * @tc.desc: test special return of Next, including throw exception and return undefined
192  * @tc.type: FUNC
193  * @tc.require:
194  */
HWTEST_F_L0(JSAPITreeSetIteratorTest,SpecialReturnOfNext)195 HWTEST_F_L0(JSAPITreeSetIteratorTest, SpecialReturnOfNext)
196 {
197     JSHandle<JSAPITreeSet> jsTreeSet = CreateTreeSet();
198     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
199     JSHandle<JSAPITreeSetIterator> treeSetIterator = factory->NewJSAPITreeSetIterator(jsTreeSet, IterationKind::KEY);
200     treeSetIterator->SetIteratedSet(thread, JSTaggedValue::Undefined());
201 
202     // test Next exception
203     {
204         auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
205         ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
206         ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
207 
208         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
209         JSTaggedValue result = JSAPITreeSetIterator::Next(ecmaRuntimeCallInfo);
210         TestHelper::TearDownFrame(thread, prev);
211         EXPECT_EQ(result, JSTaggedValue::Exception());
212         EXPECT_EXCEPTION();
213     }
214 
215     // test Next return undefined
216     {
217         auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
218         ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
219         ecmaRuntimeCallInfo->SetThis(treeSetIterator.GetTaggedValue());
220 
221         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
222         JSTaggedValue result = JSAPITreeSetIterator::Next(ecmaRuntimeCallInfo);
223         TestHelper::TearDownFrame(thread, prev);
224         EXPECT_EQ(result, thread->GetEcmaVM()->GetGlobalEnv()->GetUndefinedIteratorResult().GetTaggedValue());
225     }
226 }
227 
HWTEST_F_L0(JSAPITreeSetIteratorTest,KEY_AND_VALUE_Next)228 HWTEST_F_L0(JSAPITreeSetIteratorTest, KEY_AND_VALUE_Next)
229 {
230     constexpr uint32_t DEFAULT_LENGTH = 8;
231     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
232     JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined());
233     JSHandle<JSTaggedValue> valueStr = thread->GlobalConstants()->GetHandledValueString();
234     JSHandle<JSAPITreeSet> jsTreeSet = CreateTreeSet();
235     std::string setKey("setkey");
236     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
237         std::string ikey = setKey + std::to_string(i + 1U);
238         key.Update(factory->NewFromStdString(ikey).GetTaggedValue());
239         JSAPITreeSet::Add(thread, jsTreeSet, key);
240     }
241     // Create Iterator with KEY_AND_VALUE
242     JSHandle<JSAPITreeSetIterator> treeSetIterator =
243         factory->NewJSAPITreeSetIterator(jsTreeSet, IterationKind::KEY_AND_VALUE);
244     // traversal iterator
245     for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) {
246         auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
247         ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
248         ecmaRuntimeCallInfo->SetThis(treeSetIterator.GetTaggedValue());
249 
250         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
251         JSTaggedValue result = JSAPITreeSetIterator::Next(ecmaRuntimeCallInfo);
252         TestHelper::TearDownFrame(thread, prev);
253 
254         JSHandle<JSObject> resultObj(thread, result);
255         std::string resultKeyAndValue = setKey + std::to_string(i + 1U);
256         key.Update(factory->NewFromStdString(resultKeyAndValue).GetTaggedValue());
257 
258         JSHandle<JSTaggedValue> keyValueArr(JSObject::GetProperty(thread, resultObj, valueStr).GetValue());
259         for (int index = 0; index < 2; index++) {
260             JSHandle<JSTaggedValue> indexValue(thread, JSTaggedValue(index));
261             EXPECT_EQ(JSTaggedValue::SameValue(thread,
262                 JSObject::GetProperty(thread, keyValueArr, indexValue).GetValue(), key), true);
263         }
264         EXPECT_EQ(treeSetIterator->GetNextIndex(), (i + 1U));
265     }
266 }
267 }  // namespace panda::ecmascript
268