/* * Copyright (c) 2022 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_api/js_api_queue.h" #include "ecmascript/containers/containers_private.h" #include "ecmascript/global_env.h" #include "ecmascript/tests/ecma_test_common.h" using namespace panda::ecmascript; namespace panda::test { class JSAPIQueueTest : public BaseTestWithScope { protected: JSHandle CreateQueue(int capacaty = JSAPIQueue::DEFAULT_CAPACITY_LENGTH) { return EcmaContainerCommon::CreateQueue(thread, capacaty); } JSHandle TestCommon(JSMutableHandle& value, std::string& queueValue, uint32_t len) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle jsQueue = CreateQueue(); for (uint32_t i = 0; i < len; i++) { std::string ivalue = queueValue + std::to_string(i); value.Update(factory->NewFromStdString(ivalue).GetTaggedValue()); JSAPIQueue::Add(thread, jsQueue, value); } return jsQueue; } }; HWTEST_F_L0(JSAPIQueueTest, queueCreate) { JSHandle jsQueue = CreateQueue(); EXPECT_TRUE(*jsQueue != nullptr); } HWTEST_F_L0(JSAPIQueueTest, AddAndHasAndSetAndGet) { constexpr uint32_t DEFAULT_LENGTH = 8; JSMutableHandle value(thread, JSTaggedValue::Undefined()); std::string queueValue("queuevalue"); JSHandle jsQueue = TestCommon(value, queueValue, DEFAULT_LENGTH); EXPECT_EQ(jsQueue->GetSize(), DEFAULT_LENGTH); EXPECT_EQ(JSAPIQueue::GetArrayLength(thread, jsQueue), DEFAULT_LENGTH); ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); // test Set, Has and Get std::string ivalue = queueValue + std::to_string(10); value.Update(factory->NewFromStdString(ivalue).GetTaggedValue()); EXPECT_FALSE(jsQueue->Has(value.GetTaggedValue())); jsQueue->Set(thread, 0, value.GetTaggedValue()); EXPECT_EQ(jsQueue->Get(thread, 0), value.GetTaggedValue()); EXPECT_TRUE(jsQueue->Has(value.GetTaggedValue())); // test Get exception JSTaggedValue result = jsQueue->Get(thread, DEFAULT_LENGTH); EXPECT_EQ(result, JSTaggedValue::Exception()); EXPECT_EXCEPTION(); } HWTEST_F_L0(JSAPIQueueTest, PopFirstAndGetFirst) { constexpr uint32_t DEFAULT_LENGTH = 8; ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSMutableHandle value(thread, JSTaggedValue::Undefined()); JSHandle jsQueue = CreateQueue(); // test GetFirst and pop of empty queue EXPECT_EQ(JSAPIQueue::GetFirst(thread, jsQueue), JSTaggedValue::Undefined()); EXPECT_EQ(JSAPIQueue::Pop(thread, jsQueue), JSTaggedValue::Undefined()); std::string queueValue("queuevalue"); for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) { std::string ivalue = queueValue + std::to_string(i); value.Update(factory->NewFromStdString(ivalue).GetTaggedValue()); JSAPIQueue::Add(thread, jsQueue, value); } // test GetFirst EXPECT_EQ(JSAPIQueue::GetArrayLength(thread, jsQueue), DEFAULT_LENGTH); std::string firstValue = queueValue + std::to_string(0U); value.Update(factory->NewFromStdString(firstValue).GetTaggedValue()); EXPECT_TRUE(JSTaggedValue::SameValue( JSHandle(thread, JSAPIQueue::GetFirst(thread, jsQueue)), value)); // test Pop for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) { std::string ivalue = queueValue + std::to_string(i); value.Update(factory->NewFromStdString(ivalue).GetTaggedValue()); EXPECT_TRUE(JSTaggedValue::SameValue( JSHandle(thread, JSAPIQueue::Pop(thread, jsQueue)), value)); EXPECT_EQ(JSAPIQueue::GetArrayLength(thread, jsQueue), (DEFAULT_LENGTH - i - 1U)); } } HWTEST_F_L0(JSAPIQueueTest, OwnKeys) { constexpr uint32_t DEFAULT_LENGTH = 8; JSMutableHandle value(thread, JSTaggedValue::Undefined()); std::string queueValue("queuevalue"); JSHandle jsQueue = TestCommon(value, queueValue, DEFAULT_LENGTH); JSHandle arrayKey = JSAPIQueue::OwnKeys(thread, jsQueue); EXPECT_EQ(arrayKey->GetLength(), DEFAULT_LENGTH); for (int32_t i = 0; i < static_cast(DEFAULT_LENGTH); i++) { ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*(base::NumberHelper::NumberToString(thread, JSTaggedValue(i))), EcmaString::Cast(arrayKey->Get(i).GetTaggedObject()))); } } HWTEST_F_L0(JSAPIQueueTest, GetNextPosition) { constexpr uint32_t DEFAULT_LENGTH = 8; ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSMutableHandle value(thread, JSTaggedValue::Undefined()); std::string queueValue("queuevalue"); JSHandle jsQueue = TestCommon(value, queueValue, DEFAULT_LENGTH); // test GetNextPosition EXPECT_EQ(jsQueue->GetSize(), DEFAULT_LENGTH); for (uint32_t i = 0; i < DEFAULT_LENGTH;) { std::string ivalue = queueValue + std::to_string(i); value.Update(factory->NewFromStdString(ivalue).GetTaggedValue()); EXPECT_EQ(jsQueue->Get(thread, i), value.GetTaggedValue()); i = jsQueue->GetNextPosition(i); } } HWTEST_F_L0(JSAPIQueueTest, GetOwnProperty) { constexpr uint32_t DEFAULT_LENGTH = 8; JSMutableHandle value(thread, JSTaggedValue::Undefined()); std::string queueValue("queuevalue"); JSHandle jsQueue = TestCommon(value, queueValue, DEFAULT_LENGTH); // test GetOwnProperty int testInt = 1; JSHandle queueKey1(thread, JSTaggedValue(testInt)); EXPECT_TRUE(JSAPIQueue::GetOwnProperty(thread, jsQueue, queueKey1)); testInt = 9; JSHandle queueKey2(thread, JSTaggedValue(testInt)); EXPECT_FALSE(JSAPIQueue::GetOwnProperty(thread, jsQueue, queueKey2)); EXPECT_EXCEPTION(); // test GetOwnProperty exception JSHandle undefined(thread, JSTaggedValue::Undefined()); EXPECT_FALSE(JSAPIQueue::GetOwnProperty(thread, jsQueue, undefined)); EXPECT_EXCEPTION(); } /** * @tc.name: GetProperty * @tc.desc: * @tc.type: FUNC * @tc.require: */ HWTEST_F_L0(JSAPIQueueTest, GetProperty) { JSHandle jsQueue = CreateQueue(); uint32_t elementsNums = 8; for (uint32_t i = 0; i < elementsNums; i++) { JSHandle value(thread, JSTaggedValue(i)); JSAPIQueue::Add(thread, jsQueue, value); } for (uint32_t i = 0; i < elementsNums; i++) { JSHandle key(thread, JSTaggedValue(i)); OperationResult getPropertyRes = JSAPIQueue::GetProperty(thread, jsQueue, key); EXPECT_EQ(getPropertyRes.GetValue().GetTaggedValue(), JSTaggedValue(i)); } } /** * @tc.name: SetProperty * @tc.desc: * @tc.type: FUNC * @tc.require: */ HWTEST_F_L0(JSAPIQueueTest, SetProperty) { JSHandle jsQueue = CreateQueue(); uint32_t elementsNums = 8; for (uint32_t i = 0; i < elementsNums; i++) { JSHandle value(thread, JSTaggedValue(i)); JSAPIQueue::Add(thread, jsQueue, value); } for (uint32_t i = 0; i < elementsNums; i++) { JSHandle key(thread, JSTaggedValue(i)); JSHandle value(thread, JSTaggedValue(i * 2)); // 2 : It means double bool setPropertyRes = JSAPIQueue::SetProperty(thread, jsQueue, key, value); EXPECT_EQ(setPropertyRes, true); } JSHandle key(thread, JSTaggedValue(-1)); JSHandle value(thread, JSTaggedValue(-1)); EXPECT_FALSE(JSAPIQueue::SetProperty(thread, jsQueue, key, value)); JSHandle key1(thread, JSTaggedValue(elementsNums)); EXPECT_FALSE(JSAPIQueue::SetProperty(thread, jsQueue, key1, value)); } /** * @tc.name: GrowCapacity * @tc.desc: * @tc.type: FUNC * @tc.require: */ HWTEST_F_L0(JSAPIQueueTest, GrowCapacity) { JSHandle jsQueue = CreateQueue(0); JSHandle value(thread, JSTaggedValue(0)); JSHandle element(thread, jsQueue->GetElements()); EXPECT_EQ(element->GetLength(), 0U); JSAPIQueue::Add(thread, jsQueue, value); JSHandle newElement(thread, jsQueue->GetElements()); EXPECT_EQ(newElement->GetLength(), static_cast(JSAPIQueue::DEFAULT_CAPACITY_LENGTH)); } } // namespace panda::test