diff --git a/ecmascript/tests/BUILD.gn b/ecmascript/tests/BUILD.gn index bb90ff48c86785783d204402c2ac7dd2d54db12a..b731555aa6e66b90cf58279de77879bcecb076ba 100644 --- a/ecmascript/tests/BUILD.gn +++ b/ecmascript/tests/BUILD.gn @@ -961,6 +961,34 @@ host_unittest_action("JsSerializerTest") { } } + +host_unittest_action("JsSetIteratorTest") { + module_out_path = module_output_path + + sources = [ + # test file + "js_set_iterator_test.cpp", + ] + + configs = [ + "//ark/js_runtime:ecma_test_config", + "//ark/js_runtime:ark_jsruntime_public_config", # should add before + # arkruntime_public_config + "//ark/js_runtime:ark_jsruntime_common_config", + "$ark_root/runtime:arkruntime_public_config", + ] + + deps = [ + "$ark_root/libpandabase:libarkbase", + "//ark/js_runtime:libark_jsruntime_test", + sdk_libc_secshared_dep, + ] + + if (!is_standard_system) { + deps += [ "$ark_root/runtime:libarkruntime" ] + } +} + host_unittest_action("GcTest") { module_out_path = module_output_path @@ -1017,6 +1045,7 @@ group("unittest") { ":JsPromiseTest", ":JsProxyTest", ":JsSerializerTest", + ":JsSetIteratorTest", ":JsSetTest", ":JsSymbolTest", ":JsTaggedQueueTest", @@ -1061,6 +1090,7 @@ group("host_unittest") { ":JsPromiseTestAction", ":JsProxyTestAction", ":JsSerializerTestAction", + ":JsSetIteratorTestAction", ":JsSetTestAction", ":JsSymbolTestAction", ":JsTaggedQueueTestAction", diff --git a/ecmascript/tests/js_set_iterator_test.cpp b/ecmascript/tests/js_set_iterator_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b049ba407fccbf88453e06aaf13a0a53e7d7c010 --- /dev/null +++ b/ecmascript/tests/js_set_iterator_test.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ecmascript/js_set_iterator.h" +#include "ecmascript/js_set.h" +#include "ecmascript/global_env.h" +#include "ecmascript/linked_hash_table-inl.h" +#include "ecmascript/object_factory.h" +#include "ecmascript/tests/test_helper.h" + +using namespace panda::ecmascript; + +namespace panda::test { +class JSSetIteratorTest : public testing::Test { +public: + static void SetUpTestCase() + { + GTEST_LOG_(INFO) << "SetUpTestCase"; + } + + static void TearDownTestCase() + { + GTEST_LOG_(INFO) << "TearDownCase"; + } + + void SetUp() override + { + TestHelper::CreateEcmaVMWithScope(instance, thread, scope); + } + + void TearDown() override + { + TestHelper::DestroyEcmaVMWithScope(instance, scope); + } + ecmascript::EcmaHandleScope *scope {nullptr}; + PandaVM *instance {nullptr}; + JSThread *thread {nullptr}; +}; + +JSSet *CreateSet(JSThread *thread) +{ + ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); + JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); + + JSHandle constructor = env->GetBuiltinsSetFunction(); + JSHandle set = + JSHandle::Cast(factory->NewJSObjectByConstructor(JSHandle(constructor), constructor)); + LinkedHashSet *hashSet = LinkedHashSet::Cast(LinkedHashSet::Create(thread).GetTaggedObject()); + set->SetLinkedSet(thread, JSTaggedValue(hashSet)); + return JSSet::Cast(set.GetTaggedValue().GetTaggedObject()); +} + +/* + * Feature: JSSetIterator + * Function: CreateSetIterator + * SubFunction: GetIterationKind,GetNextIndex + * FunctionPoints: Create SetIterator + * CaseDescription: Check whether the returned value through "CreateSetIterator" function is within expectations. + */ +HWTEST_F_L0(JSSetIteratorTest, CreateSetIterator) +{ + JSHandle jsSet(thread, CreateSet(thread)); + EXPECT_TRUE(*jsSet != nullptr); + + JSHandle setIteratorValue1 = + JSSetIterator::CreateSetIterator(thread, JSHandle(jsSet), IterationKind::KEY); + + EXPECT_EQ(setIteratorValue1->IsJSSetIterator(), true); + JSHandle setIterator1(setIteratorValue1); + EXPECT_EQ(JSTaggedValue::SameValue(setIterator1->GetIteratedSet(), jsSet->GetLinkedSet()), true); + EXPECT_EQ(setIterator1->GetNextIndex().GetInt(), 0); + + JSTaggedValue iterationKind1 = setIterator1->GetIterationKind(); + EXPECT_EQ(JSTaggedValue::SameValue(iterationKind1, JSTaggedValue(static_cast(IterationKind::KEY))), true); + + JSHandle setIteratorValue2 = + JSSetIterator::CreateSetIterator(thread, JSHandle(jsSet), IterationKind::VALUE); + + EXPECT_EQ(setIteratorValue2->IsJSSetIterator(), true); + JSHandle setIterator2(setIteratorValue2); + EXPECT_EQ(JSTaggedValue::SameValue(setIterator2->GetIteratedSet(), jsSet->GetLinkedSet()), true); + EXPECT_EQ(setIterator2->GetNextIndex().GetInt(), 0); + + JSTaggedValue iterationKind2 = setIterator2->GetIterationKind(); + EXPECT_EQ(JSTaggedValue::SameValue(iterationKind2, JSTaggedValue(static_cast(IterationKind::VALUE))), true); +} + +/* + * Feature: JSSetIterator + * Function: next + * SubFunction: IteratorValue + * FunctionPoints: get next value in setiterator + * CaseDescription: Check whether the return value obtained by the function is the next value in the array element. + */ +HWTEST_F_L0(JSSetIteratorTest, Next) +{ + JSHandle jsSet(thread, CreateSet(thread)); + EXPECT_TRUE(*jsSet != nullptr); + + for (int i = 0; i < 3; i++) { + JSHandle key(thread, JSTaggedValue(i)); + JSSet::Add(thread, jsSet, key); + } + + // set IterationKind(key or value) + JSHandle setIteratorValue = + JSSetIterator::CreateSetIterator(thread, JSHandle(jsSet), IterationKind::KEY); + JSHandle setIterator(setIteratorValue); + + auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); + ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined()); + ecmaRuntimeCallInfo->SetThis(setIteratorValue.GetTaggedValue()); + ecmaRuntimeCallInfo->SetCallArg(0, JSTaggedValue::Undefined()); + [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo.get()); + + JSTaggedValue result1 = JSSetIterator::Next(ecmaRuntimeCallInfo.get()); + EXPECT_EQ(setIterator->GetNextIndex().GetInt(), 1); + JSHandle resultObj1(thread, result1); + EXPECT_EQ(0, JSIterator::IteratorValue(thread, resultObj1)->GetInt()); + + JSTaggedValue result2 = JSSetIterator::Next(ecmaRuntimeCallInfo.get()); + EXPECT_EQ(setIterator->GetNextIndex().GetInt(), 2); + JSHandle resultObj2(thread, result2); + EXPECT_EQ(1, JSIterator::IteratorValue(thread, resultObj2)->GetInt()); + + JSTaggedValue result3 = JSSetIterator::Next(ecmaRuntimeCallInfo.get()); + EXPECT_EQ(setIterator->GetNextIndex().GetInt(), 3); + JSHandle resultObj3(thread, result3); + EXPECT_EQ(2, JSIterator::IteratorValue(thread, resultObj3)->GetInt()); + + JSTaggedValue result4 = JSSetIterator::Next(ecmaRuntimeCallInfo.get()); + JSHandle resultObj4(thread, result4); + EXPECT_EQ(JSIterator::IteratorValue(thread, resultObj4).GetTaggedValue(), JSTaggedValue::Undefined()); + + TestHelper::TearDownFrame(thread, prev); +} +} // namespace panda::test