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/containers/containers_queue.h" 17#include "ecmascript/containers/containers_private.h" 18#include "ecmascript/ecma_runtime_call_info.h" 19#include "ecmascript/global_env.h" 20#include "ecmascript/js_api/js_api_queue.h" 21#include "ecmascript/js_api/js_api_queue_iterator.h" 22#include "ecmascript/js_handle.h" 23#include "ecmascript/js_tagged_value-inl.h" 24#include "ecmascript/js_thread.h" 25#include "ecmascript/object_factory.h" 26#include "ecmascript/tests/test_helper.h" 27#include "ecmascript/containers/tests/containers_test_helper.h" 28 29using namespace panda::ecmascript; 30using namespace panda::ecmascript::containers; 31 32namespace panda::test { 33class ContainersQueueTest : public testing::Test { 34public: 35 static void SetUpTestCase() 36 { 37 GTEST_LOG_(INFO) << "SetUpTestCase"; 38 } 39 40 static void TearDownTestCase() 41 { 42 GTEST_LOG_(INFO) << "TearDownCase"; 43 } 44 45 void SetUp() override 46 { 47 TestHelper::CreateEcmaVMWithScope(instance, thread, scope); 48 } 49 50 void TearDown() override 51 { 52 TestHelper::DestroyEcmaVMWithScope(instance, scope); 53 } 54 55 EcmaVM *instance {nullptr}; 56 EcmaHandleScope *scope {nullptr}; 57 JSThread *thread {nullptr}; 58protected: 59 JSTaggedValue InitializeQueueConstructor() 60 { 61 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 62 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 63 64 JSHandle<JSTaggedValue> globalObject = env->GetJSGlobalObject(); 65 JSHandle<JSTaggedValue> key(factory->NewFromASCII("ArkPrivate")); 66 JSHandle<JSTaggedValue> value = 67 JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(globalObject), key).GetValue(); 68 69 auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); 70 objCallInfo->SetFunction(JSTaggedValue::Undefined()); 71 objCallInfo->SetThis(value.GetTaggedValue()); 72 objCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int>(ContainerTag::Queue))); 73 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo); 74 JSTaggedValue result = ContainersPrivate::Load(objCallInfo); 75 TestHelper::TearDownFrame(thread, prev); 76 77 return result; 78 } 79 80 JSHandle<JSAPIQueue> CreateJSAPIQueue(JSTaggedValue compare = JSTaggedValue::Undefined()) 81 { 82 JSHandle<JSTaggedValue> compareHandle(thread, compare); 83 JSHandle<JSFunction> newTarget(thread, InitializeQueueConstructor()); 84 auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); 85 objCallInfo->SetFunction(newTarget.GetTaggedValue()); 86 objCallInfo->SetNewTarget(newTarget.GetTaggedValue()); 87 objCallInfo->SetThis(JSTaggedValue::Undefined()); 88 objCallInfo->SetCallArg(0, compareHandle.GetTaggedValue()); 89 90 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo); 91 JSTaggedValue result = ContainersQueue::QueueConstructor(objCallInfo); 92 TestHelper::TearDownFrame(thread, prev); 93 JSHandle<JSAPIQueue> queue(thread, result); 94 return queue; 95 } 96}; 97 98HWTEST_F_L0(ContainersQueueTest, QueueConstructor) 99{ 100 InitializeQueueConstructor(); 101 JSHandle<JSFunction> newTarget(thread, InitializeQueueConstructor()); 102 103 auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); 104 objCallInfo->SetFunction(newTarget.GetTaggedValue()); 105 objCallInfo->SetNewTarget(newTarget.GetTaggedValue()); 106 objCallInfo->SetThis(JSTaggedValue::Undefined()); 107 108 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo); 109 JSTaggedValue result = ContainersQueue::QueueConstructor(objCallInfo); 110 TestHelper::TearDownFrame(thread, prev); 111 112 ASSERT_TRUE(result.IsJSAPIQueue()); 113 JSHandle<JSAPIQueue> queue(thread, result); 114 JSTaggedValue resultProto = JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(queue)); 115 JSTaggedValue funcProto = newTarget->GetFunctionPrototype(); 116 ASSERT_EQ(resultProto, funcProto); 117 118 // test QueueConstructor exception 119 objCallInfo->SetNewTarget(JSTaggedValue::Undefined()); 120 CONTAINERS_API_EXCEPTION_TEST(ContainersQueue, QueueConstructor, objCallInfo); 121} 122 123HWTEST_F_L0(ContainersQueueTest, ProxyOfGetSize) 124{ 125 constexpr uint32_t NODE_NUMBERS = 8; 126 JSHandle<JSAPIQueue> queue = CreateJSAPIQueue(); 127 auto callInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); 128 callInfo->SetFunction(JSTaggedValue::Undefined()); 129 JSHandle<JSProxy> proxy = CreateJSProxyHandle(thread); 130 proxy->SetTarget(thread, queue.GetTaggedValue()); 131 callInfo->SetThis(proxy.GetTaggedValue()); 132 133 for (uint32_t i = 0; i < NODE_NUMBERS; i++) { 134 callInfo->SetCallArg(0, JSTaggedValue(i)); 135 callInfo->SetCallArg(1, JSTaggedValue(i + 1)); 136 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, callInfo); 137 ContainersQueue::Add(callInfo); 138 TestHelper::TearDownFrame(thread, prev); 139 140 [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, callInfo); 141 JSTaggedValue retult = ContainersQueue::GetSize(callInfo); 142 TestHelper::TearDownFrame(thread, prev1); 143 EXPECT_EQ(retult, JSTaggedValue(i + 1)); 144 } 145} 146 147HWTEST_F_L0(ContainersQueueTest, ExceptionReturn) 148{ 149 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersQueue, Add); 150 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersQueue, GetFirst); 151 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersQueue, Pop); 152 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersQueue, ForEach); 153 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersQueue, GetIteratorObj); 154 CONTAINERS_API_TYPE_MISMATCH_EXCEPTION_TEST(ContainersQueue, GetSize); 155} 156} // namespace panda::test 157