• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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/builtins/builtins_weak_set.h"
17 #include "ecmascript/ecma_string.h"
18 #include "ecmascript/ecma_vm.h"
19 #include "ecmascript/global_env.h"
20 #include "ecmascript/js_array.h"
21 #include "ecmascript/js_handle.h"
22 #include "ecmascript/js_hclass.h"
23 #include "ecmascript/js_object-inl.h"
24 #include "ecmascript/js_set_iterator.h"
25 #include "ecmascript/js_tagged_value.h"
26 #include "ecmascript/js_thread.h"
27 
28 #include "ecmascript/js_weak_container.h"
29 #include "ecmascript/object_factory.h"
30 #include "ecmascript/tests/test_helper.h"
31 #include "utils/bit_utils.h"
32 
33 using namespace panda::ecmascript;
34 using namespace panda::ecmascript::builtins;
35 
36 namespace panda::test {
37 using BuiltinsWeakSet = ecmascript::builtins::BuiltinsWeakSet;
38 using JSWeakSet = ecmascript::JSWeakSet;
39 
40 class BuiltinsWeakSetTest : public testing::Test {
41 public:
SetUpTestCase()42     static void SetUpTestCase()
43     {
44         GTEST_LOG_(INFO) << "SetUpTestCase";
45     }
46 
TearDownTestCase()47     static void TearDownTestCase()
48     {
49         GTEST_LOG_(INFO) << "TearDownCase";
50     }
51 
SetUp()52     void SetUp() override
53     {
54         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
55     }
56 
TearDown()57     void TearDown() override
58     {
59         TestHelper::DestroyEcmaVMWithScope(instance, scope);
60     }
61 
62     PandaVM *instance {nullptr};
63     EcmaHandleScope *scope {nullptr};
64     JSThread *thread {nullptr};
65 };
66 
JSObjectTestCreate(JSThread * thread)67 static JSObject *JSObjectTestCreate(JSThread *thread)
68 {
69     [[maybe_unused]] EcmaHandleScope scope(thread);
70     EcmaVM *ecmaVM = thread->GetEcmaVM();
71     JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
72     JSHandle<JSTaggedValue> jsFunc = globalEnv->GetObjectFunction();
73     JSHandle<JSObject> newObj =
74         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(jsFunc), jsFunc);
75     return *newObj;
76 }
77 
CreateBuiltinsWeakSet(JSThread * thread)78 JSWeakSet *CreateBuiltinsWeakSet(JSThread *thread)
79 {
80     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
81     JSHandle<JSFunction> newTarget(env->GetBuiltinsWeakSetFunction());
82 
83     // 4 : test case
84     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 4);
85     ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
86     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
87     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo.get());
88     JSTaggedValue result = BuiltinsWeakSet::WeakSetConstructor(ecmaRuntimeCallInfo.get());
89 
90     EXPECT_TRUE(result.IsECMAObject());
91     JSWeakSet *jsWeakSet = JSWeakSet::Cast(reinterpret_cast<TaggedObject *>(result.GetRawData()));
92     return jsWeakSet;
93 }
94 
HWTEST_F_L0(BuiltinsWeakSetTest,CreateAndGetSize)95 HWTEST_F_L0(BuiltinsWeakSetTest, CreateAndGetSize)
96 {
97     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
98     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
99     JSHandle<JSFunction> newTarget(env->GetBuiltinsWeakSetFunction());
100     JSHandle<JSWeakSet> weakSet(thread, CreateBuiltinsWeakSet(thread));
101 
102     JSHandle<TaggedArray> array(factory->NewTaggedArray(5));
103     for (int i = 0; i < 5; i++) {
104         JSHandle<JSTaggedValue> key(thread, JSObjectTestCreate(thread));
105         array->Set(thread, i, key.GetTaggedValue());
106     }
107 
108     JSHandle<JSArray> values = JSArray::CreateArrayFromList(thread, array);
109     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
110     ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
111     ecmaRuntimeCallInfo->SetThis(weakSet.GetTaggedValue());
112     ecmaRuntimeCallInfo->SetCallArg(0, values.GetTaggedValue());
113     ecmaRuntimeCallInfo->SetNewTarget(newTarget.GetTaggedValue());
114 
115     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo.get());
116 
117     JSTaggedValue result1 = BuiltinsWeakSet::WeakSetConstructor(ecmaRuntimeCallInfo.get());
118     JSHandle<JSWeakSet> weakSetResult(thread,
119                                         JSWeakSet::Cast(reinterpret_cast<TaggedObject *>(result1.GetRawData())));
120     EXPECT_EQ(weakSetResult->GetSize(), 5);
121 }
122 
HWTEST_F_L0(BuiltinsWeakSetTest,AddAndHas)123 HWTEST_F_L0(BuiltinsWeakSetTest, AddAndHas)
124 {
125     // create jsWeakSet
126     JSHandle<JSWeakSet> weakSet(thread, CreateBuiltinsWeakSet(thread));
127     JSHandle<JSTaggedValue> key(thread, JSObjectTestCreate(thread));
128     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
129     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
130     ecmaRuntimeCallInfo->SetThis(weakSet.GetTaggedValue());
131     ecmaRuntimeCallInfo->SetCallArg(0, key.GetTaggedValue());
132 
133     JSWeakSet *jsWeakSet;
134     {
135         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo.get());
136         JSTaggedValue result1 = BuiltinsWeakSet::Has(ecmaRuntimeCallInfo.get());
137 
138         EXPECT_EQ(result1.GetRawData(), JSTaggedValue::False().GetRawData());
139 
140         // test Add()
141         JSTaggedValue result2 = BuiltinsWeakSet::Add(ecmaRuntimeCallInfo.get());
142         EXPECT_TRUE(result2.IsECMAObject());
143         jsWeakSet = JSWeakSet::Cast(reinterpret_cast<TaggedObject *>(result2.GetRawData()));
144         EXPECT_EQ(jsWeakSet->GetSize(), 1);
145     }
146 
147     // test Has()
148     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
149     ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
150     ecmaRuntimeCallInfo1->SetThis(JSTaggedValue(jsWeakSet));
151     ecmaRuntimeCallInfo1->SetCallArg(0, key.GetTaggedValue());
152     {
153         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1.get());
154         JSTaggedValue result3 = BuiltinsWeakSet::Has(ecmaRuntimeCallInfo1.get());
155 
156         EXPECT_EQ(result3.GetRawData(), JSTaggedValue::True().GetRawData());
157     }
158 }
159 
HWTEST_F_L0(BuiltinsWeakSetTest,DeleteAndRemove)160 HWTEST_F_L0(BuiltinsWeakSetTest, DeleteAndRemove)
161 {
162     // create jsSet
163     JSHandle<JSWeakSet> weakSet(thread, CreateBuiltinsWeakSet(thread));
164 
165     // add 40 keys
166     JSTaggedValue lastKey(JSTaggedValue::Undefined());
167     for (int i = 0; i < 40; i++) {
168         JSHandle<JSTaggedValue> key(thread, JSObjectTestCreate(thread));
169 
170         auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
171         ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
172         ecmaRuntimeCallInfo->SetThis(weakSet.GetTaggedValue());
173         ecmaRuntimeCallInfo->SetCallArg(0, key.GetTaggedValue());
174 
175         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo.get());
176         JSTaggedValue result1 = BuiltinsWeakSet::Add(ecmaRuntimeCallInfo.get());
177 
178         EXPECT_TRUE(result1.IsECMAObject());
179         JSWeakSet *jsWeakSet = JSWeakSet::Cast(reinterpret_cast<TaggedObject *>(result1.GetRawData()));
180         EXPECT_EQ(jsWeakSet->GetSize(), i + 1);
181         lastKey = key.GetTaggedValue();
182     }
183     // whether jsWeakSet has delete lastKey
184 
185     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
186     ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
187     ecmaRuntimeCallInfo1->SetThis(weakSet.GetTaggedValue());
188     ecmaRuntimeCallInfo1->SetCallArg(0, lastKey);
189 
190     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1.get());
191     JSTaggedValue result2 = BuiltinsWeakSet::Has(ecmaRuntimeCallInfo1.get());
192 
193     EXPECT_EQ(result2.GetRawData(), JSTaggedValue::True().GetRawData());
194 
195     // delete
196     JSTaggedValue result3 = BuiltinsWeakSet::Delete(ecmaRuntimeCallInfo1.get());
197 
198     EXPECT_EQ(result3.GetRawData(), JSTaggedValue::True().GetRawData());
199 
200     // check deleteKey is deleted
201     JSTaggedValue result4 = BuiltinsWeakSet::Has(ecmaRuntimeCallInfo1.get());
202 
203     EXPECT_EQ(result4.GetRawData(), JSTaggedValue::False().GetRawData());
204 }
205 }  // namespace panda::test
206