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/js_api/js_api_queue.h" 17#include "ecmascript/containers/containers_private.h" 18#include "ecmascript/global_env.h" 19#include "ecmascript/tests/ecma_test_common.h" 20 21using namespace panda::ecmascript; 22 23namespace panda::test { 24class JSAPIQueueTest : public BaseTestWithScope<false> { 25protected: 26 JSHandle<JSAPIQueue> CreateQueue(int capacaty = JSAPIQueue::DEFAULT_CAPACITY_LENGTH) 27 { 28 return EcmaContainerCommon::CreateQueue(thread, capacaty); 29 } 30 31 JSHandle<JSAPIQueue> TestCommon(JSMutableHandle<JSTaggedValue>& value, std::string& queueValue, uint32_t len) 32 { 33 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 34 JSHandle<JSAPIQueue> jsQueue = CreateQueue(); 35 for (uint32_t i = 0; i < len; i++) { 36 std::string ivalue = queueValue + std::to_string(i); 37 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue()); 38 JSAPIQueue::Add(thread, jsQueue, value); 39 } 40 return jsQueue; 41 } 42}; 43 44HWTEST_F_L0(JSAPIQueueTest, queueCreate) 45{ 46 JSHandle<JSAPIQueue> jsQueue = CreateQueue(); 47 EXPECT_TRUE(*jsQueue != nullptr); 48} 49 50HWTEST_F_L0(JSAPIQueueTest, AddAndHasAndSetAndGet) 51{ 52 constexpr uint32_t DEFAULT_LENGTH = 8; 53 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined()); 54 std::string queueValue("queuevalue"); 55 JSHandle<JSAPIQueue> jsQueue = TestCommon(value, queueValue, DEFAULT_LENGTH); 56 EXPECT_EQ(jsQueue->GetSize(), DEFAULT_LENGTH); 57 EXPECT_EQ(JSAPIQueue::GetArrayLength(thread, jsQueue), DEFAULT_LENGTH); 58 59 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 60 // test Set, Has and Get 61 std::string ivalue = queueValue + std::to_string(10); 62 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue()); 63 EXPECT_FALSE(jsQueue->Has(value.GetTaggedValue())); 64 jsQueue->Set(thread, 0, value.GetTaggedValue()); 65 EXPECT_EQ(jsQueue->Get(thread, 0), value.GetTaggedValue()); 66 EXPECT_TRUE(jsQueue->Has(value.GetTaggedValue())); 67 68 // test Get exception 69 JSTaggedValue result = jsQueue->Get(thread, DEFAULT_LENGTH); 70 EXPECT_EQ(result, JSTaggedValue::Exception()); 71 EXPECT_EXCEPTION(); 72} 73 74HWTEST_F_L0(JSAPIQueueTest, PopFirstAndGetFirst) 75{ 76 constexpr uint32_t DEFAULT_LENGTH = 8; 77 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 78 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined()); 79 JSHandle<JSAPIQueue> jsQueue = CreateQueue(); 80 81 // test GetFirst and pop of empty queue 82 EXPECT_EQ(JSAPIQueue::GetFirst(thread, jsQueue), JSTaggedValue::Undefined()); 83 EXPECT_EQ(JSAPIQueue::Pop(thread, jsQueue), JSTaggedValue::Undefined()); 84 85 std::string queueValue("queuevalue"); 86 for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) { 87 std::string ivalue = queueValue + std::to_string(i); 88 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue()); 89 JSAPIQueue::Add(thread, jsQueue, value); 90 } 91 92 // test GetFirst 93 EXPECT_EQ(JSAPIQueue::GetArrayLength(thread, jsQueue), DEFAULT_LENGTH); 94 std::string firstValue = queueValue + std::to_string(0U); 95 value.Update(factory->NewFromStdString(firstValue).GetTaggedValue()); 96 EXPECT_TRUE(JSTaggedValue::SameValue( 97 JSHandle<JSTaggedValue>(thread, JSAPIQueue::GetFirst(thread, jsQueue)), value)); 98 // test Pop 99 for (uint32_t i = 0; i < DEFAULT_LENGTH; i++) { 100 std::string ivalue = queueValue + std::to_string(i); 101 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue()); 102 EXPECT_TRUE(JSTaggedValue::SameValue( 103 JSHandle<JSTaggedValue>(thread, JSAPIQueue::Pop(thread, jsQueue)), value)); 104 EXPECT_EQ(JSAPIQueue::GetArrayLength(thread, jsQueue), (DEFAULT_LENGTH - i - 1U)); 105 } 106} 107 108HWTEST_F_L0(JSAPIQueueTest, OwnKeys) 109{ 110 constexpr uint32_t DEFAULT_LENGTH = 8; 111 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined()); 112 113 std::string queueValue("queuevalue"); 114 JSHandle<JSAPIQueue> jsQueue = TestCommon(value, queueValue, DEFAULT_LENGTH); 115 116 JSHandle<TaggedArray> arrayKey = JSAPIQueue::OwnKeys(thread, jsQueue); 117 EXPECT_EQ(arrayKey->GetLength(), DEFAULT_LENGTH); 118 for (int32_t i = 0; i < static_cast<int32_t>(DEFAULT_LENGTH); i++) { 119 ASSERT_TRUE(EcmaStringAccessor::StringsAreEqual(*(base::NumberHelper::NumberToString(thread, JSTaggedValue(i))), 120 EcmaString::Cast(arrayKey->Get(i).GetTaggedObject()))); 121 } 122} 123 124HWTEST_F_L0(JSAPIQueueTest, GetNextPosition) 125{ 126 constexpr uint32_t DEFAULT_LENGTH = 8; 127 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); 128 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined()); 129 std::string queueValue("queuevalue"); 130 JSHandle<JSAPIQueue> jsQueue = TestCommon(value, queueValue, DEFAULT_LENGTH); 131 // test GetNextPosition 132 EXPECT_EQ(jsQueue->GetSize(), DEFAULT_LENGTH); 133 for (uint32_t i = 0; i < DEFAULT_LENGTH;) { 134 std::string ivalue = queueValue + std::to_string(i); 135 value.Update(factory->NewFromStdString(ivalue).GetTaggedValue()); 136 EXPECT_EQ(jsQueue->Get(thread, i), value.GetTaggedValue()); 137 i = jsQueue->GetNextPosition(i); 138 } 139} 140 141HWTEST_F_L0(JSAPIQueueTest, GetOwnProperty) 142{ 143 constexpr uint32_t DEFAULT_LENGTH = 8; 144 JSMutableHandle<JSTaggedValue> value(thread, JSTaggedValue::Undefined()); 145 std::string queueValue("queuevalue"); 146 JSHandle<JSAPIQueue> jsQueue = TestCommon(value, queueValue, DEFAULT_LENGTH); 147 // test GetOwnProperty 148 int testInt = 1; 149 JSHandle<JSTaggedValue> queueKey1(thread, JSTaggedValue(testInt)); 150 EXPECT_TRUE(JSAPIQueue::GetOwnProperty(thread, jsQueue, queueKey1)); 151 testInt = 9; 152 JSHandle<JSTaggedValue> queueKey2(thread, JSTaggedValue(testInt)); 153 EXPECT_FALSE(JSAPIQueue::GetOwnProperty(thread, jsQueue, queueKey2)); 154 EXPECT_EXCEPTION(); 155 156 // test GetOwnProperty exception 157 JSHandle<JSTaggedValue> undefined(thread, JSTaggedValue::Undefined()); 158 EXPECT_FALSE(JSAPIQueue::GetOwnProperty(thread, jsQueue, undefined)); 159 EXPECT_EXCEPTION(); 160} 161 162/** 163 * @tc.name: GetProperty 164 * @tc.desc: 165 * @tc.type: FUNC 166 * @tc.require: 167 */ 168HWTEST_F_L0(JSAPIQueueTest, GetProperty) 169{ 170 JSHandle<JSAPIQueue> jsQueue = CreateQueue(); 171 uint32_t elementsNums = 8; 172 for (uint32_t i = 0; i < elementsNums; i++) { 173 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i)); 174 JSAPIQueue::Add(thread, jsQueue, value); 175 } 176 for (uint32_t i = 0; i < elementsNums; i++) { 177 JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i)); 178 OperationResult getPropertyRes = JSAPIQueue::GetProperty(thread, jsQueue, key); 179 EXPECT_EQ(getPropertyRes.GetValue().GetTaggedValue(), JSTaggedValue(i)); 180 } 181} 182 183/** 184 * @tc.name: SetProperty 185 * @tc.desc: 186 * @tc.type: FUNC 187 * @tc.require: 188 */ 189HWTEST_F_L0(JSAPIQueueTest, SetProperty) 190{ 191 JSHandle<JSAPIQueue> jsQueue = CreateQueue(); 192 uint32_t elementsNums = 8; 193 for (uint32_t i = 0; i < elementsNums; i++) { 194 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i)); 195 JSAPIQueue::Add(thread, jsQueue, value); 196 } 197 for (uint32_t i = 0; i < elementsNums; i++) { 198 JSHandle<JSTaggedValue> key(thread, JSTaggedValue(i)); 199 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(i * 2)); // 2 : It means double 200 bool setPropertyRes = JSAPIQueue::SetProperty(thread, jsQueue, key, value); 201 EXPECT_EQ(setPropertyRes, true); 202 } 203 JSHandle<JSTaggedValue> key(thread, JSTaggedValue(-1)); 204 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(-1)); 205 EXPECT_FALSE(JSAPIQueue::SetProperty(thread, jsQueue, key, value)); 206 JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(elementsNums)); 207 EXPECT_FALSE(JSAPIQueue::SetProperty(thread, jsQueue, key1, value)); 208} 209 210/** 211 * @tc.name: GrowCapacity 212 * @tc.desc: 213 * @tc.type: FUNC 214 * @tc.require: 215 */ 216HWTEST_F_L0(JSAPIQueueTest, GrowCapacity) 217{ 218 JSHandle<JSAPIQueue> jsQueue = CreateQueue(0); 219 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(0)); 220 JSHandle<TaggedArray> element(thread, jsQueue->GetElements()); 221 EXPECT_EQ(element->GetLength(), 0U); 222 JSAPIQueue::Add(thread, jsQueue, value); 223 JSHandle<TaggedArray> newElement(thread, jsQueue->GetElements()); 224 EXPECT_EQ(newElement->GetLength(), static_cast<uint32_t>(JSAPIQueue::DEFAULT_CAPACITY_LENGTH)); 225} 226} // namespace panda::test