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/ecma_string.h" 17#include "ecmascript/ecma_vm.h" 18#include "ecmascript/global_env.h" 19#include "ecmascript/js_function.h" 20#include "ecmascript/js_handle.h" 21#include "ecmascript/js_iterator.h" 22#include "ecmascript/js_object-inl.h" 23#include "ecmascript/js_set.h" 24#include "ecmascript/js_set_iterator.h" 25#include "ecmascript/js_tagged_value.h" 26#include "ecmascript/linked_hash_table.h" 27#include "ecmascript/object_factory.h" 28#include "ecmascript/tagged_hash_table.h" 29#include "ecmascript/tests/test_helper.h" 30 31using namespace panda; 32 33using namespace panda::ecmascript; 34 35namespace panda::test { 36class JSSetTest : public BaseTestWithScope<false> { 37protected: 38 JSSet *CreateSet() 39 { 40 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 41 42 JSHandle<JSTaggedValue> constructor = thread->GetEcmaVM()->GetGlobalEnv()->GetBuiltinsSetFunction(); 43 JSHandle<JSSet> set = 44 JSHandle<JSSet>::Cast(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor)); 45 JSHandle<LinkedHashSet> hashSet = LinkedHashSet::Create(thread); 46 set->SetLinkedSet(thread, hashSet); 47 return JSSet::Cast(set.GetTaggedValue().GetTaggedObject()); 48 } 49}; 50 51HWTEST_F_L0(JSSetTest, SetCreate) 52{ 53 JSSet *set = CreateSet(); 54 EXPECT_TRUE(set != nullptr); 55} 56 57HWTEST_F_L0(JSSetTest, AddAndHas) 58{ 59 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 60 // create jsSet 61 JSHandle<JSSet> set(thread, CreateSet()); 62 63 JSHandle<JSTaggedValue> key(factory->NewFromASCII("key")); 64 JSSet::Add(thread, set, key); 65 EXPECT_TRUE(set->Has(thread, key.GetTaggedValue())); 66} 67 68HWTEST_F_L0(JSSetTest, DeleteAndGet) 69{ 70 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 71 // create jsSet 72 JSHandle<JSSet> set(thread, CreateSet()); 73 74 // add 40 keys 75 char keyArray[] = "key0"; 76 for (uint32_t i = 0; i < 40; i++) { 77 keyArray[3] = '1' + i; 78 JSHandle<JSTaggedValue> key(factory->NewFromASCII(keyArray)); 79 JSSet::Add(thread, set, key); 80 EXPECT_TRUE(set->Has(thread, key.GetTaggedValue())); 81 } 82 EXPECT_EQ(set->GetSize(), 40); 83 // whether jsSet has delete key 84 keyArray[3] = '1' + 8; 85 JSHandle<JSTaggedValue> deleteKey(factory->NewFromASCII(keyArray)); 86 JSSet::Delete(thread, set, deleteKey); 87 EXPECT_FALSE(set->Has(thread, deleteKey.GetTaggedValue())); 88 EXPECT_EQ(set->GetSize(), 39); 89} 90 91HWTEST_F_L0(JSSetTest, Iterator) 92{ 93 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 94 JSHandle<JSSet> set(thread, CreateSet()); 95 for (int i = 0; i < 5; i++) { 96 JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i)); 97 JSSet::Add(thread, set, key); 98 } 99 100 JSHandle<JSTaggedValue> keyIter(factory->NewJSSetIterator(set, IterationKind::KEY)); 101 JSHandle<JSTaggedValue> valueIter(factory->NewJSSetIterator(set, IterationKind::VALUE)); 102 103 JSHandle<JSTaggedValue> keyResult0 = JSIterator::IteratorStep(thread, keyIter); 104 JSHandle<JSTaggedValue> valueResult0 = JSIterator::IteratorStep(thread, valueIter); 105 106 EXPECT_EQ(0, JSIterator::IteratorValue(thread, keyResult0)->GetInt()); 107 EXPECT_EQ(0, JSIterator::IteratorValue(thread, valueResult0)->GetInt()); 108 109 JSHandle<JSTaggedValue> keyResult1 = JSIterator::IteratorStep(thread, keyIter); 110 EXPECT_EQ(1, JSIterator::IteratorValue(thread, keyResult1)->GetInt()); 111 112 for (int i = 0; i < 3; i++) { 113 JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i)); 114 JSSet::Delete(thread, set, key); 115 } 116 117 JSHandle<JSTaggedValue> keyResult2 = JSIterator::IteratorStep(thread, keyIter); 118 EXPECT_EQ(3, JSIterator::IteratorValue(thread, keyResult2)->GetInt()); 119 JSHandle<JSTaggedValue> keyResult3 = JSIterator::IteratorStep(thread, keyIter); 120 EXPECT_EQ(4, JSIterator::IteratorValue(thread, keyResult3)->GetInt()); 121 JSHandle<JSTaggedValue> key(thread, JSTaggedValue(5)); 122 JSSet::Add(thread, set, key); 123 JSHandle<JSTaggedValue> keyResult4 = JSIterator::IteratorStep(thread, keyIter); 124 EXPECT_EQ(5, JSIterator::IteratorValue(thread, keyResult4)->GetInt()); 125 JSHandle<JSTaggedValue> keyResult5 = JSIterator::IteratorStep(thread, keyIter); 126 EXPECT_EQ(JSTaggedValue::False(), keyResult5.GetTaggedValue()); 127} 128} // namespace panda::test 129