• 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_set_iterator.h"
17 #include "ecmascript/global_env.h"
18 #include "ecmascript/js_array.h"
19 #include "ecmascript/js_set.h"
20 #include "ecmascript/linked_hash_table.h"
21 #include "ecmascript/tests/ecma_test_common.h"
22 
23 using namespace panda;
24 using namespace panda::ecmascript;
25 
26 namespace panda::test {
27 class JSSetIteratorTest : public BaseTestWithScope<false> {
28 };
29 
CreateJSSet(JSThread * thread)30 static JSSet *CreateJSSet(JSThread *thread)
31 {
32     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
33     JSHandle<JSTaggedValue> constructor = thread->GetEcmaVM()->GetGlobalEnv()->GetBuiltinsSetFunction();
34     JSHandle<JSSet> set =
35         JSHandle<JSSet>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor));
36     JSHandle<LinkedHashSet> hashSet = LinkedHashSet::Create(thread);
37     set->SetLinkedSet(thread, hashSet);
38     return JSSet::Cast(set.GetTaggedValue().GetTaggedObject());
39 }
40 
41 /**
42  * @tc.name: CreateSetIterator
43  * @tc.desc: Call "CreateSetIterator" function create SetIterator,Check whether the the attribute setting of SetIterator
44  *           through "GetNextIndex" and "GetIterationKind" function is within expectations.
45  * @tc.type: FUNC
46  * @tc.require:
47  */
HWTEST_F_L0(JSSetIteratorTest,CreateSetIterator)48 HWTEST_F_L0(JSSetIteratorTest, CreateSetIterator)
49 {
50     JSHandle<JSSet> jsSet(thread, CreateJSSet(thread));
51     EXPECT_TRUE(*jsSet != nullptr);
52 
53     JSHandle<JSTaggedValue> setIteratorValue1 =
54         JSSetIterator::CreateSetIterator(thread, JSHandle<JSTaggedValue>(jsSet), IterationKind::KEY);
55 
56     EXPECT_EQ(setIteratorValue1->IsJSSetIterator(), true);
57     JSHandle<JSSetIterator> setIterator1(setIteratorValue1);
58     EXPECT_EQ(JSTaggedValue::SameValue(setIterator1->GetIteratedSet(), jsSet->GetLinkedSet()), true);
59     EXPECT_EQ(setIterator1->GetNextIndex(), 0U);
60     EXPECT_EQ(setIterator1->GetIterationKind(), IterationKind::KEY);
61 
62     JSHandle<JSTaggedValue> setIteratorValue2 =
63         JSSetIterator::CreateSetIterator(thread, JSHandle<JSTaggedValue>(jsSet), IterationKind::VALUE);
64 
65     EXPECT_EQ(setIteratorValue2->IsJSSetIterator(), true);
66     JSHandle<JSSetIterator> setIterator2(setIteratorValue2);
67     EXPECT_EQ(JSTaggedValue::SameValue(setIterator2->GetIteratedSet(), jsSet->GetLinkedSet()), true);
68     EXPECT_EQ(setIterator2->GetNextIndex(), 0U);
69     EXPECT_EQ(setIterator2->GetIterationKind(), IterationKind::VALUE);
70 }
71 
72 /**
73  * @tc.name: Update
74  * @tc.desc: Call "NewJSSetIterator" function create SetIterator with emty IteratedSet,create other JSSet and add key
75  *           to it,the old JSSet call "Rehash" function set new JSSet to the next table, then SetIterator call "Update"
76  *           function upadate IteratedSet,check whether the IteratedSet is within expectations.
77  * @tc.type: FUNC
78  * @tc.require:
79  */
HWTEST_F_L0(JSSetIteratorTest,Update)80 HWTEST_F_L0(JSSetIteratorTest, Update)
81 {
82     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
83     JSHandle<JSSet> jsSet1(thread, CreateJSSet(thread));
84     JSHandle<JSSet> jsSet2(thread, CreateJSSet(thread));
85 
86     JSHandle<JSTaggedValue> keyHandle1(factory->NewFromASCII("key1"));
87     JSHandle<JSTaggedValue> keyHandle2(factory->NewFromASCII("key2"));
88     JSHandle<JSTaggedValue> keyHandle3(factory->NewFromASCII("key3"));
89     // add key to jsSet2
90     JSSet::Add(thread, jsSet2, keyHandle1);
91     JSSet::Add(thread, jsSet2, keyHandle2);
92     JSSet::Add(thread, jsSet2, keyHandle3);
93 
94     JSHandle<LinkedHashSet> setHandle1(thread, LinkedHashSet::Cast(jsSet1->GetLinkedSet().GetTaggedObject()));
95     JSHandle<LinkedHashSet> setHandle2(thread, LinkedHashSet::Cast(jsSet2->GetLinkedSet().GetTaggedObject()));
96     setHandle1->Rehash(thread, *setHandle2);
97     // create SetIterator with jsSet1
98     JSHandle<JSSetIterator> setIterator = factory->NewJSSetIterator(jsSet1, IterationKind::KEY);
99     // update SetIterator
100     setIterator->Update(thread);
101     LinkedHashSet *resultSet = LinkedHashSet::Cast(setIterator->GetIteratedSet().GetTaggedObject());
102     EXPECT_TRUE(resultSet->Has(thread, keyHandle1.GetTaggedValue()));
103     EXPECT_TRUE(resultSet->Has(thread, keyHandle2.GetTaggedValue()));
104     EXPECT_TRUE(resultSet->Has(thread, keyHandle3.GetTaggedValue()));
105 }
106 
NextCommon(JSThread * thread,JSHandle<JSSetIterator> & setIterator,IterationKind kind=IterationKind::KEY)107 EcmaRuntimeCallInfo* NextCommon(JSThread *thread, JSHandle<JSSetIterator>& setIterator,
108     IterationKind kind = IterationKind::KEY)
109 {
110     JSHandle<JSSet> jsSet(thread, CreateJSSet(thread));
111     EXPECT_TRUE(*jsSet != nullptr);
112 
113     for (int i = 0; i < 3; i++) {  // 3 : 3 default numberOfElements
114         JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i));
115         JSSet::Add(thread, jsSet, key);
116     }
117     // set IterationKind(key or value)
118     JSHandle<JSTaggedValue> setIteratorValue =
119         JSSetIterator::CreateSetIterator(thread, JSHandle<JSTaggedValue>(jsSet), kind);
120     setIterator = JSHandle<JSSetIterator>(setIteratorValue);
121     std::vector<JSTaggedValue> args{JSTaggedValue::Undefined()};
122     auto ecmaRuntimeCallInfo =
123         TestHelper::CreateEcmaRuntimeCallInfo(thread, args, 6, setIteratorValue.GetTaggedValue());
124     return ecmaRuntimeCallInfo;
125 }
126 /**
127  * @tc.name: Next
128  * @tc.desc: get the next value in setiterator,Check whether the return value obtained by the function is
129  *           the next value in the array element.
130  * @tc.type: FUNC
131  * @tc.require:
132  */
HWTEST_F_L0(JSSetIteratorTest,KEY_Next)133 HWTEST_F_L0(JSSetIteratorTest, KEY_Next)
134 {
135     JSHandle<JSSetIterator> setIterator;
136     auto ecmaRuntimeCallInfo = NextCommon(thread, setIterator);
137     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
138 
139     for (int i = 0; i <= 3; i++) { // 3 : 3 default numberOfElements
140         JSTaggedValue result = JSSetIterator::Next(ecmaRuntimeCallInfo);
141         JSHandle<JSTaggedValue> resultObj(thread, result);
142         if (i < 3) {
143             EXPECT_EQ(setIterator->GetNextIndex(), static_cast<uint32_t>(i + 1));
144             EXPECT_EQ(i, JSIterator::IteratorValue(thread, resultObj)->GetInt());
145         }
146         else {
147             EXPECT_EQ(JSIterator::IteratorValue(thread, resultObj).GetTaggedValue(), JSTaggedValue::Undefined());
148         }
149     }
150     TestHelper::TearDownFrame(thread, prev);
151 }
152 
HWTEST_F_L0(JSSetIteratorTest,KEY_AND_VALUE_Next)153 HWTEST_F_L0(JSSetIteratorTest, KEY_AND_VALUE_Next)
154 {
155     JSHandle<JSTaggedValue> index0(thread, JSTaggedValue(0));
156     JSHandle<JSTaggedValue> index1(thread, JSTaggedValue(1));
157     JSHandle<JSSetIterator> setIterator;
158     auto ecmaRuntimeCallInfo = NextCommon(thread, setIterator, IterationKind::KEY_AND_VALUE);
159     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
160 
161     for (int i = 0; i <= 3; i++) { // 3 : 3 default numberOfElements
162         JSTaggedValue result = JSSetIterator::Next(ecmaRuntimeCallInfo);
163         JSHandle<JSTaggedValue> resultObj(thread, result);
164         if (i < 3) {
165             JSHandle<JSArray> arrayList(thread, JSIterator::IteratorValue(thread, resultObj).GetTaggedValue());
166             EXPECT_EQ(setIterator->GetNextIndex(), static_cast<uint32_t>(i+1));
167             EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(arrayList), index0).GetValue()->GetInt(), i);
168             EXPECT_EQ(JSArray::GetProperty(thread, JSHandle<JSTaggedValue>(arrayList), index1).GetValue()->GetInt(), i);
169         }
170         else {
171             EXPECT_EQ(JSIterator::IteratorValue(thread, resultObj).GetTaggedValue(), JSTaggedValue::Undefined());
172         }
173     }
174     TestHelper::TearDownFrame(thread, prev);
175 }
176 }  // namespace panda::test
177